diff --git a/backend/.run/Adoptme [desktopRun].run.xml b/backend/.run/Adoptme [desktopRun].run.xml index 01da361..3ae2a42 100644 --- a/backend/.run/Adoptme [desktopRun].run.xml +++ b/backend/.run/Adoptme [desktopRun].run.xml @@ -1,6 +1,11 @@ + \ No newline at end of file diff --git a/backend/docs/.swagger-codegen/VERSION b/backend/docs/.swagger-codegen/VERSION index a254f0a..6f495ea 100644 --- a/backend/docs/.swagger-codegen/VERSION +++ b/backend/docs/.swagger-codegen/VERSION @@ -1 +1 @@ -3.0.41 \ No newline at end of file +3.0.69 \ No newline at end of file diff --git a/backend/docs/index.html b/backend/docs/index.html index 8898a5c..ec2aee8 100644 --- a/backend/docs/index.html +++ b/backend/docs/index.html @@ -2140,7 +2140,7 @@

Status: 200 - A JSON array of user names

this.isPrimitive = !this.isAny && !this.isArray && !this.isObject; // - this.showToggle = this.schema.description || this.schema.title || this.isPrimitive && (this.schema.minimum || this.schema.maximum || this.schema.exclusiveMinimum || this.schema.exclusiveMaximum); + this.showToggle = this.schema.description || this.schema.title || this.isPrimitive && (this.schema.minimum || this.schema.maximum || this.schema.exclusiveMinimum || this.schema.exclusiveMaximum || this.schema.maxLength || this.schema.minLength || this.schema.pattern || this.schema.format); // populate isRequired property down to properties if (this.schema && Array.isArray(this.schema.required)) { diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/GeneralRoutingConfig.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/GeneralRoutingConfig.kt index 4bab0d9..da408d3 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/GeneralRoutingConfig.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/GeneralRoutingConfig.kt @@ -44,4 +44,5 @@ fun Application.configureGeneralRouting() { } class AuthenticationException : RuntimeException() + class AuthorizationException : RuntimeException() diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/auth/JwtService.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/auth/JwtService.kt index 1c35c9e..b9747d8 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/auth/JwtService.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/auth/JwtService.kt @@ -9,22 +9,24 @@ import java.util.Date const val JWT_CONFIGURATION = "MyProjectNameJWT" class JwtService { - private val issuer = "MyProjectNameServer" private val jwtSecret = System.getenv("JWT_SECRET") private val algorithm = HMAC512(jwtSecret) - val verifier: JWTVerifier = JWT - .require(algorithm) - .withIssuer(issuer) - .build() + val verifier: JWTVerifier = + JWT + .require(algorithm) + .withIssuer(issuer) + .build() - fun generateToken(databaseUser: DatabaseUser): String = JWT.create() - .withSubject("Authentication") - .withIssuer(issuer) - .withClaim("id", databaseUser.userId) - .withExpiresAt(expiresAt()) - .sign(algorithm) + fun generateToken(databaseUser: DatabaseUser): String = + JWT + .create() + .withSubject("Authentication") + .withIssuer(issuer) + .withClaim("id", databaseUser.userId) + .withExpiresAt(expiresAt()) + .sign(algorithm) @Suppress("MagicNumber") private fun expiresAt() = Date(System.currentTimeMillis() + 3_600_000 * 24) // 24 hours diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/models/DatabaseUser.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/models/DatabaseUser.kt index 7c713e2..3a4c822 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/models/DatabaseUser.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/models/DatabaseUser.kt @@ -8,5 +8,5 @@ data class DatabaseUser( val userId: Int, val email: String, val name: String, - val passwordHash: String + val passwordHash: String, ) : Serializable, Principal diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/plugins/HTTP.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/plugins/HTTP.kt index cfc443e..906e17c 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/plugins/HTTP.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/plugins/HTTP.kt @@ -24,10 +24,12 @@ fun Application.configureHTTP() { install(CachingHeaders) { options { _, outgoingContent -> when (outgoingContent.contentType?.withoutParameters()) { - ContentType.Text.CSS -> CachingOptions( - CacheControl.MaxAge(maxAgeSeconds = 24 * 60 * 60), - ZonedDateTime.of(0, 0, 1, 0, 0, 0, 0, ZoneId.systemDefault()) - ) + ContentType.Text.CSS -> + CachingOptions( + CacheControl.MaxAge(maxAgeSeconds = 24 * 60 * 60), + ZonedDateTime.of(0, 0, 1, 0, 0, 0, 0, ZoneId.systemDefault()), + ) + else -> null } } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepository.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepository.kt index 9e5cb5c..1cc1ac7 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepository.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepository.kt @@ -17,7 +17,7 @@ interface PetsRepository { size: String, color: String, status: String, - shelterId: Int? + shelterId: Int?, ): PetModel? suspend fun getPet(petId: Int): PetModel @@ -39,6 +39,6 @@ interface PetsRepository { size: String?, color: String?, status: String?, - shelterId: Int? + shelterId: Int?, ): PetModel? } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepositoryImp.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepositoryImp.kt index 72b4d71..32c258f 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepositoryImp.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/pets/PetsRepositoryImp.kt @@ -12,7 +12,6 @@ import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.deleteWhere import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.statements.InsertStatement import org.jetbrains.exposed.sql.update @@ -31,43 +30,41 @@ class PetsRepositoryImp : PetsRepository { size: String, color: String, status: String, - shelterId: Int? + shelterId: Int?, ): PetModel? { var statement: InsertStatement? = null dbQuery { - statement = Pets.insert { - it[Pets.userId] = userId - it[Pets.title] = title - it[Pets.description] = description - it[Pets.images] = images - it[Pets.category] = category - it[Pets.location] = location - it[Pets.published] = published - it[Pets.breed] = breed - it[Pets.age] = age - it[Pets.gender] = gender - it[Pets.size] = size - it[Pets.color] = color - it[Pets.status] = status - it[Pets.shelterId] = shelterId ?: 0 - } + statement = + Pets.insert { + it[Pets.userId] = userId + it[Pets.title] = title + it[Pets.description] = description + it[Pets.images] = images + it[Pets.category] = category + it[Pets.location] = location + it[Pets.published] = published + it[Pets.breed] = breed + it[Pets.age] = age + it[Pets.gender] = gender + it[Pets.size] = size + it[Pets.color] = color + it[Pets.status] = status + it[Pets.shelterId] = shelterId ?: 0 + } } return rowToPetModel(statement?.resultedValues?.get(0)) } override suspend fun getPets(userId: Int): List { return dbQuery { - Pets.select { - Pets.userId.eq((userId)) // 3 - }.mapNotNull { rowToPetModel(it) } + Pets.select(Pets.userId).where { Pets.userId.eq(userId) } + .mapNotNull { rowToPetModel(it) } } } override suspend fun getPet(petId: Int): PetModel { return dbQuery { - Pets.select { - Pets.id.eq((petId)) - }.mapNotNull { rowToPetModel(it) } + Pets.select(Pets.id).where { Pets.id.eq(petId) }.mapNotNull { rowToPetModel(it) } }.first() } @@ -92,10 +89,10 @@ class PetsRepositoryImp : PetsRepository { size: String?, color: String?, status: String?, - shelterId: Int? + shelterId: Int?, ): PetModel? { return dbQuery { - Pets.select { + Pets.select(Pets.id).where { Pets.id.eq((petId)) }.forUpdate() @@ -139,7 +136,7 @@ class PetsRepositoryImp : PetsRepository { } } - Pets.select { + Pets.select(Pets.id).where { Pets.id.eq((petId)) }.mapNotNull { rowToPetModel(it) } }.firstOrNull() @@ -166,7 +163,7 @@ class PetsRepositoryImp : PetsRepository { size = PetSize.valueOf(row[Pets.size]), color = row[Pets.color].toString(), status = PetStatus.valueOf(row[Pets.status]), - shelterId = row[Pets.shelterId] + shelterId = row[Pets.shelterId], ) } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepository.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepository.kt index 4e0d8c1..80ef281 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepository.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepository.kt @@ -3,14 +3,13 @@ package com.multiplatformkickstarter.repository.profile import com.multiplatformkickstarter.app.common.model.Profile interface ProfileRepository { - suspend fun addProfile( userId: Int, name: String, description: String?, image: String?, location: String?, - rating: Double? + rating: Double?, ): Profile? suspend fun getProfile(userId: Int): Profile? @@ -21,6 +20,6 @@ interface ProfileRepository { description: String?, image: String?, location: String?, - rating: Double? + rating: Double?, ): Profile? } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepositoryImpl.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepositoryImpl.kt index a3300e0..ca3e6b3 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepositoryImpl.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/profile/ProfileRepositoryImpl.kt @@ -6,45 +6,44 @@ import com.multiplatformkickstarter.repository.DatabaseFactory.dbQuery import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.statements.InsertStatement import org.jetbrains.exposed.sql.update class ProfileRepositoryImpl : ProfileRepository { - override suspend fun addProfile( userId: Int, name: String, description: String?, image: String?, location: String?, - rating: Double? + rating: Double?, ): Profile? { var statement: InsertStatement? = null dbQuery { - statement = Profiles.insert { profiles -> - profiles[Profiles.userId] = userId - profiles[Profiles.name] = name - description?.let { - profiles[Profiles.description] = it - } - image?.let { - profiles[Profiles.image] = it - } - location?.let { - profiles[Profiles.location] = it + statement = + Profiles.insert { profiles -> + profiles[Profiles.userId] = userId + profiles[Profiles.name] = name + description?.let { + profiles[Profiles.description] = it + } + image?.let { + profiles[Profiles.image] = it + } + location?.let { + profiles[Profiles.location] = it + } + rating?.let { + profiles[Profiles.rating] = it + } } - rating?.let { - profiles[Profiles.rating] = it - } - } } return rowToProfiles(statement?.resultedValues?.get(0)) } override suspend fun getProfile(userId: Int): Profile? { return dbQuery { - Profiles.select { + Profiles.select(Profiles.userId).where { Profiles.userId.eq((userId)) }.mapNotNull { rowToProfiles(it) } }.firstOrNull() @@ -56,10 +55,10 @@ class ProfileRepositoryImpl : ProfileRepository { description: String?, image: String?, location: String?, - rating: Double? + rating: Double?, ): Profile? { return dbQuery { - Profiles.select { + Profiles.select(Profiles.userId).where { Profiles.userId.eq((userId)) }.forUpdate() @@ -82,7 +81,7 @@ class ProfileRepositoryImpl : ProfileRepository { } } - Profiles.select { + Profiles.select(Profiles.userId).where { Profiles.userId.eq((userId)) }.mapNotNull { rowToProfiles(it) } }.firstOrNull() @@ -100,7 +99,7 @@ class ProfileRepositoryImpl : ProfileRepository { description = row[Profiles.description], image = row[Profiles.image], location = geoLocation, - rating = row[Profiles.rating] + rating = row[Profiles.rating], ) } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepository.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepository.kt index 3a2c2a9..2617b78 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepository.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepository.kt @@ -6,9 +6,10 @@ interface UserRepository { suspend fun addUser( email: String, name: String, - passwordHash: String + passwordHash: String, ): DatabaseUser? suspend fun findUser(userId: Int): DatabaseUser? + suspend fun findUserByEmail(email: String): DatabaseUser? } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepositoryImp.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepositoryImp.kt index 6ded82c..171e75f 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepositoryImp.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/repository/user/UserRepositoryImp.kt @@ -4,36 +4,38 @@ import com.multiplatformkickstarter.models.DatabaseUser import com.multiplatformkickstarter.repository.DatabaseFactory.dbQuery import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.statements.InsertStatement class UserRepositoryImp : UserRepository { override suspend fun addUser( email: String, name: String, - passwordHash: String + passwordHash: String, ): DatabaseUser? { var statement: InsertStatement? = null // 1 dbQuery { - statement = Users.insert { user -> - user[Users.email] = email - user[Users.name] = name - user[Users.passwordHash] = passwordHash - } + statement = + Users.insert { user -> + user[Users.email] = email + user[Users.name] = name + user[Users.passwordHash] = passwordHash + } } return rowToUser(statement?.resultedValues?.get(0)) } - override suspend fun findUser(userId: Int) = dbQuery { - Users.select { Users.userId.eq(userId) } - .map { rowToUser(it) }.singleOrNull() - } + override suspend fun findUser(userId: Int) = + dbQuery { + Users.select(Users.userId).where { Users.userId.eq(userId) } + .map { rowToUser(it) }.singleOrNull() + } - override suspend fun findUserByEmail(email: String) = dbQuery { - Users.select { Users.email.eq(email) } - .map { rowToUser(it) }.singleOrNull() - } + override suspend fun findUserByEmail(email: String) = + dbQuery { + Users.select(Users.email).where { Users.email.eq(email) } + .map { rowToUser(it) }.singleOrNull() + } private fun rowToUser(row: ResultRow?): DatabaseUser? { if (row == null) { @@ -43,7 +45,7 @@ class UserRepositoryImp : UserRepository { userId = row[Users.userId], email = row[Users.email], name = row[Users.name], - passwordHash = row[Users.passwordHash] + passwordHash = row[Users.passwordHash], ) } } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/PetsRoutes.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/PetsRoutes.kt index 0e6b4c6..336cd9f 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/PetsRoutes.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/PetsRoutes.kt @@ -56,7 +56,10 @@ class PetsDeleteRoute @Suppress("LongMethod", "TooGenericExceptionCaught", "CyclomaticComplexMethod") @KtorExperimentalLocationsAPI -fun Route.pets(petsRepository: PetsRepository, userRepository: UserRepository) { +fun Route.pets( + petsRepository: PetsRepository, + userRepository: UserRepository, +) { authenticate(JWT_CONFIGURATION) { post { val petsParameters = call.receive() @@ -73,34 +76,37 @@ fun Route.pets(petsRepository: PetsRepository, userRepository: UserRepository) { val status = petsParameters["status"] ?: "" val shelterId = petsParameters["shelterId"]?.toInt() ?: -1 - val user = call.sessions.get()?.let { - userRepository.findUser(it.userId) - } + val user = + call.sessions.get()?.let { + userRepository.findUser(it.userId) + } if (user == null) { call.respond(HttpStatusCode.BadRequest, "Problems retrieving User") return@post } val date = Calendar.getInstance().time - val formattedDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm", Locale.getDefault()).format(date) + val formattedDate = + SimpleDateFormat("yyyy-MM-dd'T'HH:mm", Locale.getDefault()).format(date) try { - val currentPet = petsRepository.addPet( - userId = user.userId, - title = title, - description = description, - images = images, - category = category, - location = location, - published = formattedDate, - breed = breed, - age = age, - gender = gender, - size = size, - color = color, - status = status, - shelterId = shelterId - ) + val currentPet = + petsRepository.addPet( + userId = user.userId, + title = title, + description = description, + images = images, + category = category, + location = location, + published = formattedDate, + breed = breed, + age = age, + gender = gender, + size = size, + color = color, + status = status, + shelterId = shelterId, + ) currentPet?.id?.let { call.respond(HttpStatusCode.OK, currentPet) } @@ -158,34 +164,37 @@ fun Route.pets(petsRepository: PetsRepository, userRepository: UserRepository) { val status = petsParameters["status"] ?: "" val shelterId = petsParameters["shelterId"]?.toInt() ?: -1 - val user = call.sessions.get()?.let { - userRepository.findUser(it.userId) - } + val user = + call.sessions.get()?.let { + userRepository.findUser(it.userId) + } if (user == null) { call.respond(HttpStatusCode.BadRequest, "Problems retrieving User") return@patch } val date = Calendar.getInstance().time - val formattedDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm", Locale.getDefault()).format(date) + val formattedDate = + SimpleDateFormat("yyyy-MM-dd'T'HH:mm", Locale.getDefault()).format(date) try { if (petId != null) { - val currentPet = petsRepository.updatePet( - petId = petId.toInt(), - title = title, - description = description, - images = images, - location = location, - modified = formattedDate, - breed = breed, - age = age, - gender = gender, - size = size, - color = color, - status = status, - shelterId = shelterId - ) + val currentPet = + petsRepository.updatePet( + petId = petId, + title = title, + description = description, + images = images, + location = location, + modified = formattedDate, + breed = breed, + age = age, + gender = gender, + size = size, + color = color, + status = status, + shelterId = shelterId, + ) currentPet?.id?.let { call.respond(HttpStatusCode.OK, currentPet) return@patch @@ -204,9 +213,10 @@ fun Route.pets(petsRepository: PetsRepository, userRepository: UserRepository) { val petsParameters = call.receive() val petId = petsParameters["id"]?.toInt() - val user = call.sessions.get()?.let { - userRepository.findUser(it.userId) - } + val user = + call.sessions.get()?.let { + userRepository.findUser(it.userId) + } if (user == null) { call.respond(HttpStatusCode.BadRequest, "Problems retrieving User") diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/ProfileRoutes.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/ProfileRoutes.kt index 0b65431..d8a1b4e 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/ProfileRoutes.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/ProfileRoutes.kt @@ -42,7 +42,7 @@ class ProfileUpdateRoute @KtorExperimentalLocationsAPI fun Route.profiles( profileRepository: ProfileRepository, - userRepository: UserRepository + userRepository: UserRepository, ) { authenticate(JWT_CONFIGURATION) { post { @@ -53,23 +53,25 @@ fun Route.profiles( val location = profileParameters["location"] ?: "" val rating = profileParameters["rating"] ?: "" - val user = call.sessions.get()?.let { - userRepository.findUser(it.userId) - } + val user = + call.sessions.get()?.let { + userRepository.findUser(it.userId) + } if (user == null) { call.respond(HttpStatusCode.BadRequest, "Problems retrieving User") return@post } try { - val profile = profileRepository.addProfile( - user.userId, - name = name, - description = description, - image = image, - location = location, - rating = rating.toDouble() - ) + val profile = + profileRepository.addProfile( + user.userId, + name = name, + description = description, + image = image, + location = location, + rating = rating.toDouble(), + ) profile?.id?.let { call.respond(HttpStatusCode.OK, profile) } @@ -107,23 +109,25 @@ fun Route.profiles( val location = profileParameters["location"] ?: "" val rating = profileParameters["rating"] ?: "" - val user = call.sessions.get()?.let { - userRepository.findUser(it.userId) - } + val user = + call.sessions.get()?.let { + userRepository.findUser(it.userId) + } if (user == null) { call.respond(HttpStatusCode.BadRequest, "Problems retrieving User") return@patch } try { - val profile = profileRepository.updateProfile( - userId = user.userId, - name = name, - description = description, - image = image, - location = location, - rating = rating.toDouble() - ) + val profile = + profileRepository.updateProfile( + userId = user.userId, + name = name, + description = description, + image = image, + location = location, + rating = rating.toDouble(), + ) profile?.id?.let { call.respond(HttpStatusCode.OK, profile) } diff --git a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/UserRoute.kt b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/UserRoute.kt index cc32dd9..39705e0 100644 --- a/backend/src/main/kotlin/com/multiplatformkickstarter/routes/UserRoute.kt +++ b/backend/src/main/kotlin/com/multiplatformkickstarter/routes/UserRoute.kt @@ -43,7 +43,7 @@ class UserLogoutRoute fun Route.users( userRepository: UserRepository, jwtService: JwtService, - hashFunction: (String) -> String + hashFunction: (String) -> String, ) { post { val signupParameters = call.receive() @@ -57,7 +57,7 @@ fun Route.users( call.sessions.set(UserSession(it)) call.respondText( jwtService.generateToken(newUser), - status = HttpStatusCode.Created + status = HttpStatusCode.Created, ) } } catch (e: Throwable) { diff --git a/backend/src/test/kotlin/com/multiplatformkickstarter/ApplicationTest.kt b/backend/src/test/kotlin/com/multiplatformkickstarter/ApplicationTest.kt index 3e8dfbc..0b6e948 100644 --- a/backend/src/test/kotlin/com/multiplatformkickstarter/ApplicationTest.kt +++ b/backend/src/test/kotlin/com/multiplatformkickstarter/ApplicationTest.kt @@ -9,13 +9,14 @@ import kotlin.test.assertEquals class ApplicationTest { @Test - fun testRoot() = testApplication { - application { - configureGeneralRouting() + fun testRoot() = + testApplication { + application { + configureGeneralRouting() + } + client.get("/").apply { + assertEquals(HttpStatusCode.OK, status) + assertEquals("Hello World!", bodyAsText()) + } } - client.get("/").apply { - assertEquals(HttpStatusCode.OK, status) - assertEquals("Hello World!", bodyAsText()) - } - } } diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index c151347..77e03f8 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -48,7 +48,7 @@ kotlin { listOf( iosX64(), iosArm64(), - iosSimulatorArm64() + iosSimulatorArm64(), ).forEach { iosTarget -> iosTarget.binaries.framework { baseName = "ComposeApp" diff --git a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivity.kt b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivity.kt index ce17b25..0f6e08c 100644 --- a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivity.kt +++ b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivity.kt @@ -37,13 +37,13 @@ class MainActivity : ComponentActivity() { } @Composable -fun shouldUseDarkTheme( - uiState: MainActivityUiState -): Boolean = when (uiState) { - MainActivityUiState.Loading -> isSystemInDarkTheme() - is MainActivityUiState.Success -> when (uiState.userData.darkThemeConfig) { - DarkThemeConfig.FOLLOW_SYSTEM -> isSystemInDarkTheme() - DarkThemeConfig.LIGHT -> false - DarkThemeConfig.DARK -> true +fun shouldUseDarkTheme(uiState: MainActivityUiState): Boolean = + when (uiState) { + MainActivityUiState.Loading -> isSystemInDarkTheme() + is MainActivityUiState.Success -> + when (uiState.userData.darkThemeConfig) { + DarkThemeConfig.FOLLOW_SYSTEM -> isSystemInDarkTheme() + DarkThemeConfig.LIGHT -> false + DarkThemeConfig.DARK -> true + } } -} diff --git a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivityUiState.kt b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivityUiState.kt index ab0c414..8d31fd9 100644 --- a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivityUiState.kt +++ b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MainActivityUiState.kt @@ -4,5 +4,6 @@ import com.multiplatformkickstarter.app.common.model.UserData sealed interface MainActivityUiState { data object Loading : MainActivityUiState + data class Success(val userData: UserData) : MainActivityUiState } diff --git a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MultiplatformKickstarterApplication.kt b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MultiplatformKickstarterApplication.kt index 88d412d..343ac56 100644 --- a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MultiplatformKickstarterApplication.kt +++ b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/MultiplatformKickstarterApplication.kt @@ -4,7 +4,6 @@ import android.app.Application import com.multiplatformkickstarter.app.android.core.di.DependencyContainer class MultiplatformKickstarterApplication : Application() { - override fun onCreate() { super.onCreate() initDependencyContainer() diff --git a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/SplashActivity.kt b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/SplashActivity.kt index 045a3af..8afe6e3 100644 --- a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/SplashActivity.kt +++ b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/SplashActivity.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.launch @SuppressLint("CustomSplashScreen", "RestrictedApi") class SplashActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val splashScreen = installSplashScreen() diff --git a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/core/di/DependencyContainer.kt b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/core/di/DependencyContainer.kt index 017d942..2993d9e 100644 --- a/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/core/di/DependencyContainer.kt +++ b/composeApp/src/androidMain/kotlin/com/multiplatformkickstarter/app/android/core/di/DependencyContainer.kt @@ -11,7 +11,6 @@ import org.koin.core.logger.Level import org.koin.core.module.Module object DependencyContainer { - @VisibleForTesting var testModules: MutableList = mutableListOf() diff --git a/composeApp/src/commonMain/kotlin/App.kt b/composeApp/src/commonMain/kotlin/App.kt index 746d63e..f7e5acd 100644 --- a/composeApp/src/commonMain/kotlin/App.kt +++ b/composeApp/src/commonMain/kotlin/App.kt @@ -2,6 +2,7 @@ import androidx.compose.runtime.Composable import com.multiplatformkickstarter.app.MainApp import org.jetbrains.compose.ui.tooling.preview.Preview +@Suppress("FunctionName") @Composable @Preview fun App() { diff --git a/composeApp/src/desktopMain/kotlin/Main.kt b/composeApp/src/desktopMain/kotlin/Main.kt index a5484ba..73004a3 100644 --- a/composeApp/src/desktopMain/kotlin/Main.kt +++ b/composeApp/src/desktopMain/kotlin/Main.kt @@ -1,4 +1,3 @@ - import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import com.multiplatformkickstarter.app.MainApp @@ -6,13 +5,14 @@ import com.multiplatformkickstarter.app.di.commonModule import com.multiplatformkickstarter.app.ui.theme.MultiplatformKickstarterTheme import org.koin.core.context.startKoin -fun main() = application { - startKoin { - modules(commonModule) - } - Window(onCloseRequest = ::exitApplication) { - MultiplatformKickstarterTheme { - MainApp() +fun main() = + application { + startKoin { + modules(commonModule) + } + Window(onCloseRequest = ::exitApplication) { + MultiplatformKickstarterTheme { + MainApp() + } } } -} diff --git a/composeApp/src/iosMain/kotlin/MainViewController.kt b/composeApp/src/iosMain/kotlin/MainViewController.kt index 77fffaf..098d6eb 100644 --- a/composeApp/src/iosMain/kotlin/MainViewController.kt +++ b/composeApp/src/iosMain/kotlin/MainViewController.kt @@ -2,8 +2,7 @@ import androidx.compose.ui.window.ComposeUIViewController import com.multiplatformkickstarter.app.MainApp import platform.UIKit.UIViewController -fun homeScreenViewController(): UIViewController = ComposeUIViewController { - MainApp() -} - -/* ktlint-disable */ +fun homeScreenViewController(): UIViewController = + ComposeUIViewController { + MainApp() + } diff --git a/gradle.properties b/gradle.properties index a4824f1..c10e7fd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,5 +34,5 @@ kotlin.native.cachekind=none # Multiplatform Kickstarter config multiplatformkickstarter.version.major = 2 -multiplatformkickstarter.version.minor = 1 +multiplatformkickstarter.version.minor = 2 multiplatformkickstarter.version.patch = 0 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 380907e..5cf11ec 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,28 +2,28 @@ android-compileSdk = "35" android-minSdk = "26" android-targetSdk = "35" -kotlin = "2.1.10" +kotlin = "2.1.21" ktor-client = "2.3.12" ktor-server = "2.3.12" -multiplatform-settings = "1.0.0" +multiplatform-settings = "1.3.0" voyager = "1.1.0-beta03" -koin = "4.0.1" -koin-compose = "4.0.1" +koin = "4.1.0" +koin-compose = "4.1.0" junit = "4.13.2" -androidGradlePlugin = "8.8.2" -composeMultiplatform = "1.7.3" -exposed = "0.37.3" +androidGradlePlugin = "8.11.0" +composeMultiplatform = "1.8.2" +exposed = "0.61.0" skiko = "0.8.18" -ktlint = "11.5.1" -detekt = "1.23.7" +ktlint = "12.3.0" +detekt = "1.23.8" kotlinx-coroutines = "1.10.2" androidx-junit = "1.2.1" espressoCore = "3.6.1" accompanistSystemuicontroller = "0.36.0" activityCompose = "1.10.1" -firebase = "33.13.0" -touchlab = "2.0.5" -navigationCommonKtx = "2.8.9" +firebase = "33.16.0" +touchlab = "2.1.0" +navigationCommonKtx = "2.9.1" [libraries] # Common @@ -39,10 +39,10 @@ skiko = { module = "org.jetbrains.skiko:skiko", version.ref = "skiko" } skiko-macos-arm64 = { module = "org.jetbrains.skiko:skiko-awt-runtime-macos-arm64", version.ref = "skiko" } ktor-client = { module = "io.ktor:ktor-client-core", version.ref = "ktor-client" } kamel = "media.kamel:kamel-image:0.7.1" -kermit = "co.touchlab:kermit:2.0.0-RC5" +kermit = "co.touchlab:kermit:2.0.6" kotlinx-serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1" -kotlinx-datetime = "org.jetbrains.kotlinx:kotlinx-datetime:0.6.0" +kotlinx-datetime = "org.jetbrains.kotlinx:kotlinx-datetime:0.7.0" kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } @@ -56,7 +56,7 @@ koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" } # Android -compose-bom = "androidx.compose:compose-bom:2025.01.00" +compose-bom = "androidx.compose:compose-bom:2025.06.01" koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" } androidx-core-ktx = "androidx.core:core-ktx:1.16.0" @@ -85,7 +85,7 @@ stately-common = { module = "co.touchlab:stately-common", version.ref = "touchla koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin-compose" } kotlinx-coroutines-swingui = "org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.10.2" ktor-client-java = { module = "io.ktor:ktor-client-java", version.ref = "ktor-client" } -androidx-compose-ui-util = "androidx.compose.ui:ui-util:1.7.5" +androidx-compose-ui-util = "org.jetbrains.compose.ui:ui-util:1.8.2" # Backend ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor-server" } @@ -113,11 +113,11 @@ exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "e exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } -kotlinx-html-jvm = "org.jetbrains.kotlinx:kotlinx-html-jvm:0.9.1" -logback-classic = "ch.qos.logback:logback-classic:1.5.6" -postgresql = "org.postgresql:postgresql:42.3.8" -hikariCP = "com.zaxxer:HikariCP:5.0.1" -swagger-codegen = "io.swagger.codegen.v3:swagger-codegen-generators:1.0.38" +kotlinx-html-jvm = "org.jetbrains.kotlinx:kotlinx-html-jvm:0.12.0" +logback-classic = "ch.qos.logback:logback-classic:1.5.18" +postgresql = "org.postgresql:postgresql:42.7.7" +hikariCP = "com.zaxxer:HikariCP:6.3.0" +swagger-codegen = "io.swagger.codegen.v3:swagger-codegen-generators:1.0.57" kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } androidx-navigation-common-ktx = { group = "androidx.navigation", name = "navigation-common-ktx", version.ref = "navigationCommonKtx" } @@ -134,7 +134,7 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = " #Backend kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version = "kotlin" } -shadow = { id = "com.github.johnrengelman.shadow", version = "7.1.2" } +shadow = { id = "com.github.johnrengelman.shadow", version = "8.1.1" } [bundles] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c8..37f853b 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 1d71306..bdeeac1 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -37,7 +37,7 @@ kotlin { listOf( iosX64(), iosArm64(), - iosSimulatorArm64() + iosSimulatorArm64(), ).forEach { it.binaries.framework { baseName = "shared" diff --git a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/feature/debugmenu/Debug.android.kt b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/feature/debugmenu/Debug.android.kt index 1fccab4..a879930 100644 --- a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/feature/debugmenu/Debug.android.kt +++ b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/feature/debugmenu/Debug.android.kt @@ -1,9 +1,7 @@ package com.multiplatformkickstarter.app.feature.debugmenu -import co.touchlab.kermit.BuildConfig - class AndroidDebug : Debug { - override val isDebug: Boolean = BuildConfig.DEBUG + override val isDebug: Boolean = false } actual fun getDebug(): Debug = AndroidDebug() diff --git a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.android.kt b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.android.kt index 1a28e35..15a60cf 100644 --- a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.android.kt +++ b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.android.kt @@ -1,5 +1,6 @@ package com.multiplatformkickstarter.app.localization +import android.annotation.SuppressLint import android.content.res.Configuration import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext @@ -16,6 +17,8 @@ actual fun getCurrentLanguage(): AvailableLanguages { } } +@SuppressLint("LocalContextConfigurationRead") +@Suppress("FunctionName") @Composable actual fun SetLanguage(language: AvailableLanguages) { val context = LocalContext.current diff --git a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt index a122b68..edbe64d 100644 --- a/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt +++ b/shared/src/androidMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt @@ -9,7 +9,12 @@ import androidx.compose.ui.text.font.FontWeight @SuppressLint("DiscouragedApi") @Composable -actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font { +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font { val context = LocalContext.current val id = context.resources.getIdentifier(res, "font", context.packageName) return Font(id, weight, style) @@ -17,7 +22,10 @@ actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle) @SuppressLint("DiscouragedApi") @Composable -fun getResourceId(name: String?, resourceFolder: String?): Int { +fun getResourceId( + name: String?, + resourceFolder: String?, +): Int { val context = LocalContext.current return context.resources.getIdentifier(name, resourceFolder, context.packageName) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/MainApp.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/MainApp.kt index 3ef3ba6..179d1c9 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/MainApp.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/MainApp.kt @@ -5,6 +5,7 @@ import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.transitions.ScaleTransition import com.multiplatformkickstarter.app.ui.screens.MainScreen +@Suppress("FunctionName") @Composable fun MainApp() { Navigator(MainScreen()) { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetCategory.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetCategory.kt index f8abc97..e17d3b7 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetCategory.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetCategory.kt @@ -7,7 +7,7 @@ enum class PetCategory(val id: Int) { RABBITS(3), SMALL_AND_FURRY(4), HORSES(5), - OTHER(6); + OTHER(6),; companion object } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetModel.kt index 61782aa..58d39f7 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/PetModel.kt @@ -19,11 +19,15 @@ class PetModel( val color: String, val status: PetStatus, val shelterId: Int?, - val userId: Int + val userId: Int, ) enum class PetAge { - BABY, YOUNG, ADULT, SENIOR; + BABY, + YOUNG, + ADULT, + SENIOR, + ; companion object } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/Profile.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/Profile.kt index 5ef4c68..1b4d060 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/Profile.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/Profile.kt @@ -10,5 +10,5 @@ data class Profile( val description: String?, val image: String?, val location: GeoLocation?, - val rating: Double? + val rating: Double?, ) diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/SearchModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/SearchModel.kt index cc66ab6..9e3ae8c 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/SearchModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/SearchModel.kt @@ -9,5 +9,5 @@ data class SearchList(val list: List) data class SearchModel( val text: String? = null, val petCategory: PetCategory? = null, - val location: GeoLocation? = null + val location: GeoLocation? = null, ) diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/User.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/User.kt index d6e8910..4161f2e 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/User.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/User.kt @@ -6,11 +6,11 @@ import kotlinx.serialization.Serializable data class User( val id: Int, val name: String, - val email: String + val email: String, ) data class AuthenticationResponse( val id: Int, val session: String, - val token: String + val token: String, ) diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/UserData.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/UserData.kt index f53f36f..2e324cd 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/UserData.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/UserData.kt @@ -8,5 +8,5 @@ data class UserData( val followedTopics: Set, val followedAuthors: Set, val themeBrand: ThemeBrand, - val darkThemeConfig: DarkThemeConfig + val darkThemeConfig: DarkThemeConfig, ) diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/DarkThemeConfig.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/DarkThemeConfig.kt index 2b71502..0438172 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/DarkThemeConfig.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/DarkThemeConfig.kt @@ -1,5 +1,7 @@ package com.multiplatformkickstarter.app.common.model.theme enum class DarkThemeConfig { - FOLLOW_SYSTEM, LIGHT, DARK + FOLLOW_SYSTEM, + LIGHT, + DARK, } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/ThemeBrand.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/ThemeBrand.kt index bfcdc8a..4df46ce 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/ThemeBrand.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/model/theme/ThemeBrand.kt @@ -1,5 +1,6 @@ package com.multiplatformkickstarter.app.common.model.theme enum class ThemeBrand { - DEFAULT, ANDROID + DEFAULT, + ANDROID, } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/usecases/UseCase.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/usecases/UseCase.kt index 4000985..db6c4f0 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/usecases/UseCase.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/common/usecases/UseCase.kt @@ -6,7 +6,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext open class UseCase { - /** * This function is responsible for running the Use Case's code block into a Background Thread * [Documentation](https://developer.android.com/kotlin/coroutines/coroutines-best-practices#main-safe) @@ -14,5 +13,8 @@ open class UseCase { suspend fun execute( dispatcher: CoroutineDispatcher = Dispatchers.Default, code: suspend CoroutineScope.() -> R - ): R = withContext(dispatcher) { code() } + ): R = + withContext(dispatcher) { + code() + } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/AuthenticationRepository.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/AuthenticationRepository.kt index b182cdc..8fed1b9 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/AuthenticationRepository.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/AuthenticationRepository.kt @@ -15,7 +15,6 @@ private const val SIGN_UP_PATH = "v1/users/create" private const val LOGOUT_PATH = "v1/users/logout" class AuthenticationRepository(private val service: ServiceClient) { - suspend fun login(email: String, password: String): AuthenticationResponse { return service.httpClient.requestAndCatch( { @@ -37,9 +36,11 @@ class AuthenticationRepository(private val service: ServiceClient) { HttpStatusCode.Unauthorized -> { throw UnauthorizedException() } + HttpStatusCode.BadRequest -> { throw BadRequestException() } + else -> throw this } } @@ -51,11 +52,12 @@ class AuthenticationRepository(private val service: ServiceClient) { { val response = this.submitForm( url = "${ServerEnvironment.PRODUCTION.url}/$SIGN_UP_PATH", - formParameters = Parameters.build { - append("name", name) - append("email", email) - append("password", password) - } + formParameters = + Parameters.build { + append("name", name) + append("email", email) + append("password", password) + } ) AuthenticationResponse( id = response.headers["user_id"]?.toInt()!!, @@ -68,9 +70,11 @@ class AuthenticationRepository(private val service: ServiceClient) { HttpStatusCode.BadRequest -> { throw BadRequestException() } + HttpStatusCode.Conflict -> { throw ConflictException() } + else -> throw this } } @@ -87,9 +91,11 @@ class AuthenticationRepository(private val service: ServiceClient) { HttpStatusCode.BadRequest -> { throw BadRequestException() } + HttpStatusCode.Conflict -> { throw ConflictException() } + else -> throw this } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/LastSearchAdsMockRepository.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/LastSearchAdsMockRepository.kt index 1cdc709..c49c863 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/LastSearchAdsMockRepository.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/LastSearchAdsMockRepository.kt @@ -9,192 +9,194 @@ import com.multiplatformkickstarter.app.common.model.PetSize import com.multiplatformkickstarter.app.common.model.PetStatus class LastSearchAdsMockRepository { - private val itemList: List = listOf( - PetModel( - 0, - "Clove", - "Clove is a sweet and playful cat. She loves to play with toys and explore and loves to soak up.", - listOf("https://upload.wikimedia.org/wikipedia/commons/4/4c/Blackcat-Lilith.jpg"), - PetCategory.CATS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.FEMALE, - PetSize.MEDIUM, - "Black", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 1, - "River", - "River is sweet and gentle, she loves her human and needs lots of love.", - listOf("https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG/800px-Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG"), - PetCategory.CATS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.FEMALE, - PetSize.MEDIUM, - "Tiger", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 2, - "Louie", - "Fun dog.", - listOf("https://images.unsplash.com/photo-1560603065-d99d67c6efe5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDE0fHx8ZW58MHx8fHx8&w=1000&q=80"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Mixed Breed", - PetAge.ADULT, - PetGender.MALE, - PetSize.XLARGE, - "Black and Brown", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 3, - "Hope", - "Come and meet Hope!", - listOf("https://upload.wikimedia.org/wikipedia/commons/4/40/Harlis-2009-15-10.jpg"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Mixed Breed", - PetAge.BABY, - PetGender.MALE, - PetSize.MEDIUM, - "Brindle", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 4, - "Dennis", - "Come and meet Dennis!", - listOf("https://upload.wikimedia.org/wikipedia/commons/b/bf/Yellow_dog.jpg"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.MALE, - PetSize.SMALL, - "Yellow", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 5, - "Clove", - "Clove is a sweet and playful cat. She loves to play with toys and explore and loves to soak up.", - listOf("https://upload.wikimedia.org/wikipedia/commons/4/4c/Blackcat-Lilith.jpg"), - PetCategory.CATS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.FEMALE, - PetSize.MEDIUM, - "Black", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 6, - "River", - "River is sweet and gentle, she loves her human and needs lots of love.", - listOf("https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG/800px-Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG"), - PetCategory.CATS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.FEMALE, - PetSize.MEDIUM, - "Tiger", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 7, - "Louie", - "Fun dog.", - listOf("https://images.unsplash.com/photo-1560603065-d99d67c6efe5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDE0fHx8ZW58MHx8fHx8&w=1000&q=80"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Mixed Breed", - PetAge.ADULT, - PetGender.MALE, - PetSize.XLARGE, - "Black and Brown", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 8, - "Hope", - "Come and meet Hope!", - listOf("https://upload.wikimedia.org/wikipedia/commons/4/40/Harlis-2009-15-10.jpg"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Mixed Breed", - PetAge.BABY, - PetGender.MALE, - PetSize.MEDIUM, - "Brindle", - PetStatus.ADOPTABLE, - null, - 0 - ), - PetModel( - 9, - "Dennis", - "Come and meet Dennis!", - listOf("https://upload.wikimedia.org/wikipedia/commons/b/bf/Yellow_dog.jpg"), - PetCategory.DOGS, - GeoLocation(41.391568, 2.151914), - "2023-5-12T16:35", - "2023-5-12T16:35", - "Domestic Short Hair", - PetAge.ADULT, - PetGender.MALE, - PetSize.SMALL, - "Yellow", - PetStatus.ADOPTABLE, - null, - 0 + private val itemList: List = + listOf( + PetModel( + 0, + "Clove", + "Clove is a sweet and playful cat. She loves to play with toys and explore and loves to soak up.", + listOf("https://upload.wikimedia.org/wikipedia/commons/4/4c/Blackcat-Lilith.jpg"), + PetCategory.CATS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.FEMALE, + PetSize.MEDIUM, + "Black", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 1, + "River", + "River is sweet and gentle, she loves her human and needs lots of love.", + listOf("https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG/800px-Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG"), + PetCategory.CATS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.FEMALE, + PetSize.MEDIUM, + "Tiger", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 2, + "Louie", + "Fun dog.", + listOf("https://images.unsplash.com/photo-1560603065-d99d67c6efe5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDE0fHx8ZW58MHx8fHx8&w=1000&q=80"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Mixed Breed", + PetAge.ADULT, + PetGender.MALE, + PetSize.XLARGE, + "Black and Brown", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 3, + "Hope", + "Come and meet Hope!", + listOf("https://upload.wikimedia.org/wikipedia/commons/4/40/Harlis-2009-15-10.jpg"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Mixed Breed", + PetAge.BABY, + PetGender.MALE, + PetSize.MEDIUM, + "Brindle", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 4, + "Dennis", + "Come and meet Dennis!", + listOf("https://upload.wikimedia.org/wikipedia/commons/b/bf/Yellow_dog.jpg"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.MALE, + PetSize.SMALL, + "Yellow", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 5, + "Clove", + "Clove is a sweet and playful cat. She loves to play with toys and explore and loves to soak up.", + listOf("https://upload.wikimedia.org/wikipedia/commons/4/4c/Blackcat-Lilith.jpg"), + PetCategory.CATS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.FEMALE, + PetSize.MEDIUM, + "Black", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 6, + "River", + "River is sweet and gentle, she loves her human and needs lots of love.", + listOf("https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG/800px-Toyger_-_Cornish_Rex_presentation_show_Riihim%C3%A4ki_2008-11-16_IMG_0101.JPG"), + PetCategory.CATS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.FEMALE, + PetSize.MEDIUM, + "Tiger", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 7, + "Louie", + "Fun dog.", + listOf("https://images.unsplash.com/photo-1560603065-d99d67c6efe5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDE0fHx8ZW58MHx8fHx8&w=1000&q=80"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Mixed Breed", + PetAge.ADULT, + PetGender.MALE, + PetSize.XLARGE, + "Black and Brown", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 8, + "Hope", + "Come and meet Hope!", + listOf("https://upload.wikimedia.org/wikipedia/commons/4/40/Harlis-2009-15-10.jpg"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Mixed Breed", + PetAge.BABY, + PetGender.MALE, + PetSize.MEDIUM, + "Brindle", + PetStatus.ADOPTABLE, + null, + 0, + ), + PetModel( + 9, + "Dennis", + "Come and meet Dennis!", + listOf("https://upload.wikimedia.org/wikipedia/commons/b/bf/Yellow_dog.jpg"), + PetCategory.DOGS, + GeoLocation(41.391568, 2.151914), + "2023-5-12T16:35", + "2023-5-12T16:35", + "Domestic Short Hair", + PetAge.ADULT, + PetGender.MALE, + PetSize.SMALL, + "Yellow", + PetStatus.ADOPTABLE, + null, + 0, + ) ) - ) - fun getAds(): Result> = runCatching { - return@runCatching itemList - } + fun getAds(): Result> = + runCatching { + return@runCatching itemList + } fun getFeaturedAd(id: Int): PetModel? { return itemList.find { id == it.id } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/ProfileRepository.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/ProfileRepository.kt index ce14f49..7cab7d4 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/ProfileRepository.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/ProfileRepository.kt @@ -47,7 +47,7 @@ class ProfileRepository( getDescription(), getImage(), getLocation(), - getRating() + getRating(), ) } @@ -89,7 +89,14 @@ class ProfileRepository( return settings.getDouble(PROFILE_RATING_KEY, 0.0) } - fun initProfile(userId: Int, name: String, description: String?, image: String?, geoLocation: GeoLocation?, rating: Double?) { + fun initProfile( + userId: Int, + name: String, + description: String?, + image: String?, + geoLocation: GeoLocation?, + rating: Double?, + ) { settings.putInt(PROFILE_ID_KEY, userId) settings.putString(PROFILE_NAME_KEY, name) description?.let { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/SessionRepository.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/SessionRepository.kt index 7d94b14..f576564 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/SessionRepository.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/repositories/SessionRepository.kt @@ -9,7 +9,6 @@ const val USER_TOKEN_KEY = "USER_TOKEN_KEY" const val IS_LOGGED_IN_KEY = "IS_LOGGED_IN_KEY" class SessionRepository(private val settings: Settings) { - fun getUserId(): Int { return settings.getInt(USER_ID_KEY, -1) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/usecases/GetLastSearchUseCase.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/usecases/GetLastSearchUseCase.kt index 306c186..121fae8 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/usecases/GetLastSearchUseCase.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/data/usecases/GetLastSearchUseCase.kt @@ -11,7 +11,7 @@ class GetLastSearchUseCase( private val lastSearchesRepository: LastSearchesRepository, private val petsFromSearchRepository: PetsFromSearchRepository, private val lastSearchAdsMockRepository: LastSearchAdsMockRepository, - private val globalAppSettingsRepository: GlobalAppSettingsRepository + private val globalAppSettingsRepository: GlobalAppSettingsRepository, ) : UseCase() { suspend fun invoke(): Result> = runCatching { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/ProfileDetailScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/ProfileDetailScreen.kt index 951eee0..79ada48 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/ProfileDetailScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/ProfileDetailScreen.kt @@ -62,7 +62,12 @@ class ProfileDetailScreen(val userId: Int) : Screen { MultiplatformKickstarterTheme { val currentNavigator = LocalNavigator.currentOrThrow val viewModel = koinScreenModel( - parameters = { ParametersHolder(listOf(userId, currentNavigator).toMutableList(), false) } + parameters = { + ParametersHolder( + listOf(userId, currentNavigator).toMutableList(), + false + ) + } ) DisposableEffect(key) { @@ -77,7 +82,11 @@ class ProfileDetailScreen(val userId: Int) : Screen { } @Composable - fun ProfileDetailView(viewModel: ProfileDetailViewModel, localization: Localization, onClose: () -> Unit) { + fun ProfileDetailView( + viewModel: ProfileDetailViewModel, + localization: Localization, + onClose: () -> Unit + ) { val scrollState = rememberScrollState() val state by viewModel.state.collectAsState() @@ -92,7 +101,10 @@ class ProfileDetailScreen(val userId: Int) : Screen { TopAppBar( navigationIcon = { IconButton(onClick = { onClose.invoke() }) { - Icon(imageVector = MultiplatformKickstarterIcons.ArrowBack, contentDescription = "Go back") + Icon( + imageVector = MultiplatformKickstarterIcons.ArrowBack, + contentDescription = "Go back" + ) } }, title = {}, @@ -193,23 +205,24 @@ class ProfileDetailScreen(val userId: Int) : Screen { } ) { Column( - modifier = Modifier - .fillMaxSize() - .padding(it) - .verticalScroll(scrollState) - .background(MaterialTheme.colorScheme.background) + modifier = + Modifier + .fillMaxSize() + .padding(it) + .verticalScroll(scrollState) + .background(MaterialTheme.colorScheme.background), ) { Text( text = localization.profileScreenUserAds, style = Typography.get().titleMedium, - modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp) + modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp), ) if (state.pets.isNotEmpty()) { val itemSize: Dp = (maxWidth / 2) - 8.dp FlowRow( horizontalArrangement = Arrangement.SpaceEvenly, - maxItemsInEachRow = 2 + maxItemsInEachRow = 2, ) { state.pets.map { item -> PetCardSmall(item = item, itemSize, itemSize) { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/viewmodels/ProfileDetailViewModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/viewmodels/ProfileDetailViewModel.kt index 5dfd305..cebbfed 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/viewmodels/ProfileDetailViewModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/feature/profile/viewmodels/ProfileDetailViewModel.kt @@ -34,14 +34,15 @@ class ProfileDetailViewModel( profileRepository.getProfile(userId) } val pets = emptyList() - _state.value = ProfileDetailState( - name = profile.name, - description = profile.description, - image = profile.image, - location = profile.location, - rating = profile.rating, - pets = pets - ) + _state.value = + ProfileDetailState( + name = profile.name, + description = profile.description, + image = profile.image, + location = profile.location, + rating = profile.rating, + pets = pets, + ) } } @@ -56,7 +57,7 @@ data class ProfileDetailState( val image: String?, val location: GeoLocation?, val rating: Double?, - val pets: List + val pets: List, ) sealed class ProfileDetailSideEffects { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/FavoritesTab.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/FavoritesTab.kt index 222fc29..8aac048 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/FavoritesTab.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/FavoritesTab.kt @@ -10,7 +10,6 @@ import com.multiplatformkickstarter.app.ui.icon.MultiplatformKickstarterIcons import com.multiplatformkickstarter.app.ui.screens.ProTemplateFeature internal object FavoritesTab : Tab { - override val options: TabOptions @Composable get() { @@ -20,7 +19,7 @@ internal object FavoritesTab : Tab { TabOptions( index = 1u, title = getCurrentLocalization().favorites, - icon = icon + icon = icon, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/HomeTab.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/HomeTab.kt index d4ab0d3..4bca8a5 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/HomeTab.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/HomeTab.kt @@ -12,7 +12,6 @@ import com.multiplatformkickstarter.app.ui.icon.MultiplatformKickstarterIcons import com.multiplatformkickstarter.app.ui.screens.HomeTabScreen internal object HomeTab : Tab { - override val options: TabOptions @Composable get() { @@ -22,7 +21,7 @@ internal object HomeTab : Tab { TabOptions( index = 0u, title = getCurrentLocalization().home, - icon = icon + icon = icon, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/InboxTab.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/InboxTab.kt index 1a3719e..e8fc77e 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/InboxTab.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/InboxTab.kt @@ -10,7 +10,6 @@ import com.multiplatformkickstarter.app.ui.icon.MultiplatformKickstarterIcons import com.multiplatformkickstarter.app.ui.screens.ProTemplateFeature internal object InboxTab : Tab { - override val options: TabOptions @Composable get() { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/PetUploadTab.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/PetUploadTab.kt index baf83a9..23b0566 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/PetUploadTab.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/PetUploadTab.kt @@ -23,7 +23,7 @@ internal object PetUploadTab : Tab { TabOptions( index = 2u, title = localization.upload, - icon = icon + icon = icon, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/ProfileTab.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/ProfileTab.kt index 4ce0ff3..ff23b97 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/ProfileTab.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/navigation/ProfileTab.kt @@ -12,7 +12,6 @@ import com.multiplatformkickstarter.app.ui.icon.MultiplatformKickstarterIcons import com.multiplatformkickstarter.app.ui.screens.ProfileTabScreen internal object ProfileTab : Tab { - override val options: TabOptions @Composable get() { @@ -22,7 +21,7 @@ internal object ProfileTab : Tab { TabOptions( index = 4u, title = getCurrentLocalization().profile, - icon = icon + icon = icon, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Environment.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Environment.kt index 17b91d0..6b13834 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Environment.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Environment.kt @@ -4,6 +4,7 @@ sealed class Environment(val name: String, val url: String) sealed class ServerEnvironment(name: String, endpoint: String) : Environment(name, endpoint) { data object PRODUCTION : Environment("PRODUCTION", "http://multiplatformkickstarter.com") + data object PREPRODUCTION : Environment("PREPRODUCTION", "http://pre.multiplatformkickstarter.com") // This IP represents the localhost of your computer through the emulator diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Extensions.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Extensions.kt index 3064ea1..8f8313c 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Extensions.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Extensions.kt @@ -24,7 +24,7 @@ fun Modifier.shimmerLoadingAnimation( isLightModeActive: Boolean = true, widthOfShadowBrush: Int = 500, angleOfAxisY: Float = 270f, - durationMillis: Int = 1000 + durationMillis: Int = 1000, ): Modifier { if (isLoadingCompleted) { return this @@ -34,18 +34,19 @@ fun Modifier.shimmerLoadingAnimation( val transition = rememberInfiniteTransition(label = "") - val translateAnimation = transition.animateFloat( - initialValue = 0f, - targetValue = (durationMillis + widthOfShadowBrush).toFloat(), - animationSpec = infiniteRepeatable( - animation = tween( - durationMillis = durationMillis, - easing = LinearEasing + val translateAnimation = + transition.animateFloat( + initialValue = 0f, + targetValue = (durationMillis + widthOfShadowBrush).toFloat(), + animationSpec = infiniteRepeatable( + animation = tween( + durationMillis = durationMillis, + easing = LinearEasing + ), + repeatMode = RepeatMode.Restart ), - repeatMode = RepeatMode.Restart - ), - label = "Shimmer loading animation" - ) + label = "Shimmer loading animation", + ) this.background( brush = Brush.linearGradient( diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt index 01ff2aa..54610ec 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt @@ -6,4 +6,9 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight @Composable -expect fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font +expect fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/ServiceClient.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/ServiceClient.kt index 84d74c3..ef220ac 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/ServiceClient.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/ServiceClient.kt @@ -5,9 +5,10 @@ import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.serialization.kotlinx.json.json object ServiceClient { - val httpClient = HttpClient { - install(ContentNegotiation) { - json() + val httpClient = + HttpClient { + install(ContentNegotiation) { + json() + } } - } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/TrackingComponent.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/TrackingComponent.kt index 290d735..936dc8f 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/TrackingComponent.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/platform/TrackingComponent.kt @@ -4,7 +4,6 @@ import kotlin.native.concurrent.ThreadLocal @ThreadLocal object TrackingComponent { - private val EMPTY_TRACKER = EmptyTracker() private var tracker: Tracker = EMPTY_TRACKER @@ -37,7 +36,7 @@ enum class TrackEvents(val eventName: String) { SIGN_UP_ERROR("Sign Up Error"), PET_UPLOAD_SUCCESSFUL("Pet Upload Successful"), PET_UPLOAD_ERROR("Pet Upload Error"), - REQUEST_ERROR("Request Error") + REQUEST_ERROR("Request Error"), } interface Tracker { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/ColoredSnackBar.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/ColoredSnackBar.kt index 976b660..0ec1518 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/ColoredSnackBar.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/ColoredSnackBar.kt @@ -20,10 +20,11 @@ import com.multiplatformkickstarter.app.ui.theme.warningContainer private const val DELIMITER = "##" +@Suppress("FunctionName") @Composable fun ColoredSnackBarHost( hostState: SnackbarHostState, - action: @Composable (() -> Unit)? = null + action: @Composable (() -> Unit)? = null, ) { SnackbarHost(hostState) { val message = it.getSnackbarMessage() @@ -38,12 +39,12 @@ fun ColoredSnackBarHost( modifier = Modifier.padding(8.dp), containerColor = color.first, contentColor = color.second, - action = action + action = action, ) { hostState.currentSnackbarData?.let { Text( text = message.message, - style = Typography.get().bodyMedium + style = Typography.get().bodyMedium, ) } } @@ -55,7 +56,7 @@ suspend fun SnackbarHostState.showSnackbar( message: String, actionLabel: String? = null, withDismissAction: Boolean = false, - duration: SnackbarDuration = SnackbarDuration.Short + duration: SnackbarDuration = SnackbarDuration.Short, ): SnackbarResult { return showSnackbar(SnackbarMessage(type, message).toString(), actionLabel, withDismissAction, duration) } @@ -74,7 +75,7 @@ private data class SnackbarMessage( return SnackbarMessage( type = SnackbarType.valueOf(type), - message = message + message = message, ) } } @@ -85,5 +86,8 @@ private fun SnackbarData.getSnackbarMessage(): SnackbarMessage { } enum class SnackbarType { - SUCCESS, ERROR, INFO, WARNING + SUCCESS, + ERROR, + INFO, + WARNING } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Navigation.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Navigation.kt index e6a24bb..9db1abf 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Navigation.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Navigation.kt @@ -38,7 +38,7 @@ fun RowScope.MultiplatformKickstarterNavigationBarItem( selectedIcon: @Composable () -> Unit = icon, enabled: Boolean = true, label: @Composable (() -> Unit)? = null, - alwaysShowLabel: Boolean = true + alwaysShowLabel: Boolean = true, ) { NavigationBarItem( selected = selected, @@ -48,13 +48,14 @@ fun RowScope.MultiplatformKickstarterNavigationBarItem( enabled = enabled, label = label, alwaysShowLabel = alwaysShowLabel, - colors = NavigationBarItemDefaults.colors( - selectedIconColor = MultiplatformKickstarterNavigationDefaults.navigationSelectedItemColor(), - unselectedIconColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), - selectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationSelectedItemColor(), - unselectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), - indicatorColor = MultiplatformKickstarterNavigationDefaults.navigationIndicatorColor() - ) + colors = + NavigationBarItemDefaults.colors( + selectedIconColor = MultiplatformKickstarterNavigationDefaults.navigationSelectedItemColor(), + unselectedIconColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), + selectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationSelectedItemColor(), + unselectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), + indicatorColor = MultiplatformKickstarterNavigationDefaults.navigationIndicatorColor() + ) ) } @@ -65,16 +66,17 @@ fun RowScope.MultiplatformKickstarterNavigationBarItem( * @param content Destinations inside the navigation bar. This should contain multiple * [NavigationBarItem]s. */ +@Suppress("FunctionName") @Composable fun MultiplatformKickstarterNavigationBar( modifier: Modifier = Modifier, - content: @Composable RowScope.() -> Unit + content: @Composable RowScope.() -> Unit, ) { NavigationBar( modifier = modifier, contentColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), tonalElevation = 0.dp, - content = content + content = content, ) } @@ -102,7 +104,7 @@ fun MultiplatformKickstarterNavigationRailItem( selectedIcon: @Composable () -> Unit = icon, enabled: Boolean = true, label: @Composable (() -> Unit)? = null, - alwaysShowLabel: Boolean = true + alwaysShowLabel: Boolean = true, ) { NavigationRailItem( selected = selected, @@ -118,7 +120,7 @@ fun MultiplatformKickstarterNavigationRailItem( selectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationSelectedItemColor(), unselectedTextColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), indicatorColor = MultiplatformKickstarterNavigationDefaults.navigationIndicatorColor() - ) + ), ) } @@ -134,14 +136,14 @@ fun MultiplatformKickstarterNavigationRailItem( fun MultiplatformKickstarterNavigationRail( modifier: Modifier = Modifier, header: @Composable (ColumnScope.() -> Unit)? = null, - content: @Composable ColumnScope.() -> Unit + content: @Composable ColumnScope.() -> Unit, ) { NavigationRail( modifier = modifier, containerColor = Color.Transparent, contentColor = MultiplatformKickstarterNavigationDefaults.navigationContentColor(), header = header, - content = content + content = content, ) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/NoResultsLayout.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/NoResultsLayout.kt index 94ba7f7..4259729 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/NoResultsLayout.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/NoResultsLayout.kt @@ -33,31 +33,31 @@ fun EmptyLayout( imageResource: DrawableResource? = null, actionLabel: String? = null, localization: Localization, - action: () -> Unit + action: () -> Unit, ) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Text( modifier = Modifier.padding(16.dp), text = title ?: localization.noResultsTitle, style = MaterialTheme.typography.titleLarge, textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.primary + color = MaterialTheme.colorScheme.primary, ) Text( modifier = Modifier.padding(horizontal = 16.dp), text = description ?: localization.noResultsDesciption, style = MaterialTheme.typography.bodySmall, textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.outline + color = MaterialTheme.colorScheme.outline, ) Image( imageVector = vectorResource(imageResource ?: Res.drawable.no_data_cuate), contentDescription = description, - modifier = Modifier.size(260.dp) + modifier = Modifier.size(260.dp), ) actionLabel?.let { Spacer(modifier = Modifier.size(10.dp)) @@ -66,17 +66,18 @@ fun EmptyLayout( action.invoke() }, colors = ButtonDefaults.buttonColors(), - modifier = Modifier - .fillMaxWidth() - .size(50.dp) - .padding(start = 16.dp, end = 16.dp), + modifier = + Modifier + .fillMaxWidth() + .size(50.dp) + .padding(start = 16.dp, end = 16.dp), contentPadding = PaddingValues(0.dp), - shape = RoundedCornerShape(10) + shape = RoundedCornerShape(10), ) { Text( text = it, style = Typography.get().titleMedium, - modifier = Modifier.padding(8.dp) + modifier = Modifier.padding(8.dp), ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/OnBoarding.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/OnBoarding.kt index 4d81949..464b8c9 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/OnBoarding.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/OnBoarding.kt @@ -40,7 +40,7 @@ import org.jetbrains.compose.resources.painterResource private val defaultAction = {} class OnboardingComponent( - private val carouselItems: List + private val carouselItems: List, ) { @Composable fun DrawCarousel() { @@ -48,14 +48,14 @@ class OnboardingComponent( val state = rememberPagerState( initialPage = 0, initialPageOffsetFraction = 0f, - pageCount = { carouselItems.size } + pageCount = { carouselItems.size }, ) Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize(), ) { Box( - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) { Carousel(state, carouselItems) } @@ -75,7 +75,7 @@ class OnboardingComponent( Text( modifier = Modifier.padding(4.dp), text = item.actionText, - style = Typography.get().bodyMedium + style = Typography.get().bodyMedium, ) } } @@ -84,28 +84,31 @@ class OnboardingComponent( totalDots = carouselItems.size, selectedIndex = state.currentPage, selectedColor = Color.DarkGray, - unSelectedColor = Color.Gray + unSelectedColor = Color.Gray, ) } } @Composable - fun Carousel(state: PagerState, carouselItemsList: List) { + fun Carousel( + state: PagerState, + carouselItemsList: List, + ) { HorizontalPager( state = state, modifier = Modifier .fillMaxWidth() - .padding(top = 16.dp) + .padding(top = 16.dp), ) { val item = carouselItemsList[it] Card( modifier = Modifier .fillMaxSize() - .padding(top = 16.dp, start = 16.dp, end = 16.dp) + .padding(top = 16.dp, start = 16.dp, end = 16.dp), ) { Column( horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween + verticalArrangement = Arrangement.SpaceBetween, ) { Image( painterResource(item.imageResource), @@ -114,14 +117,14 @@ class OnboardingComponent( .fillMaxWidth() .weight(0.5f) .padding(start = 24.dp, end = 24.dp), - contentScale = ContentScale.FillWidth + contentScale = ContentScale.FillWidth, ) item.title?.let { title -> Text( modifier = Modifier.padding(16.dp), text = title, textAlign = TextAlign.Center, - style = Typography.get().headlineMedium + style = Typography.get().headlineMedium, ) } item.description?.let { description -> @@ -129,7 +132,7 @@ class OnboardingComponent( modifier = Modifier.padding(16.dp), text = description, textAlign = TextAlign.Center, - style = Typography.get().bodyLarge + style = Typography.get().bodyLarge, ) } } @@ -142,14 +145,14 @@ class OnboardingComponent( totalDots: Int, selectedIndex: Int, selectedColor: Color, - unSelectedColor: Color + unSelectedColor: Color, ) { LazyRow( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .padding(16.dp), - horizontalArrangement = Arrangement.Center + horizontalArrangement = Arrangement.Center, ) { items(totalDots) { index -> if (index == selectedIndex) { @@ -164,7 +167,7 @@ class OnboardingComponent( modifier = Modifier .size(10.dp) .clip(CircleShape) - .background(unSelectedColor) + .background(unSelectedColor), ) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardBig.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardBig.kt index 2e1334e..fc580c4 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardBig.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardBig.kt @@ -36,7 +36,7 @@ import io.kamel.image.asyncPainterResource @Composable fun PetCardBig( item: PetModel, - onClick: () -> Unit + onClick: () -> Unit, ) { val imageHeight = 120.dp val roundedCornerSize = 10.dp @@ -49,9 +49,9 @@ fun PetCardBig( shape = RoundedCornerShape(roundedCornerSize), colors = CardDefaults.cardColors( containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onBackground + contentColor = MaterialTheme.colorScheme.onBackground, ), - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { Column { KamelImage( @@ -69,7 +69,7 @@ fun PetCardBig( .background(color = MaterialTheme.colorScheme.primaryContainer) .height(imageHeight) .fillMaxWidth() - .shimmerLoadingAnimation(isLoadingCompleted = false) + .shimmerLoadingAnimation(isLoadingCompleted = false), ) }, onFailure = { @@ -79,13 +79,13 @@ fun PetCardBig( .background(color = MaterialTheme.colorScheme.primaryContainer) .height(imageHeight) .fillMaxWidth(), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Icon( modifier = Modifier.size(48.dp), imageVector = MultiplatformKickstarterIcons.BrokenImage, contentDescription = "image", - tint = MaterialTheme.colorScheme.onPrimaryContainer + tint = MaterialTheme.colorScheme.onPrimaryContainer, ) } } @@ -94,13 +94,13 @@ fun PetCardBig( text = item.title, style = Typography.get().headlineMedium, modifier = Modifier.fillMaxWidth(), - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, ) Text( text = item.description, style = Typography.get().bodyMedium, modifier = Modifier.fillMaxWidth(), - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardSmall.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardSmall.kt index 50224d1..3d2ae1f 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardSmall.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetCardSmall.kt @@ -39,7 +39,7 @@ fun PetCardSmall( item: PetModel, width: Dp, height: Dp, - onClick: () -> Unit + onClick: () -> Unit, ) { val imageHeight = 70.dp val roundedCornerSize = 10.dp @@ -52,7 +52,7 @@ fun PetCardSmall( containerColor = MaterialTheme.colorScheme.background, contentColor = MaterialTheme.colorScheme.onBackground ), - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { Column { KamelImage( @@ -70,7 +70,7 @@ fun PetCardSmall( .background(color = MaterialTheme.colorScheme.primaryContainer) .height(imageHeight) .fillMaxWidth() - .shimmerLoadingAnimation(isLoadingCompleted = false) + .shimmerLoadingAnimation(isLoadingCompleted = false), ) }, onFailure = { @@ -80,13 +80,13 @@ fun PetCardSmall( .background(color = MaterialTheme.colorScheme.primaryContainer) .height(imageHeight) .fillMaxWidth(), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Icon( modifier = Modifier.size(36.dp), imageVector = MultiplatformKickstarterIcons.BrokenImage, contentDescription = "image", - tint = MaterialTheme.colorScheme.onPrimaryContainer + tint = MaterialTheme.colorScheme.onPrimaryContainer, ) } } @@ -95,13 +95,13 @@ fun PetCardSmall( modifier = Modifier.padding(top = 6.dp), text = item.title, style = Typography.get().titleSmall, - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, ) Text( modifier = Modifier.fillMaxWidth(), text = item.description, style = Typography.get().bodySmall, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetsSearchBar.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetsSearchBar.kt index 1c1e391..dde1e11 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetsSearchBar.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/PetsSearchBar.kt @@ -34,7 +34,7 @@ import com.multiplatformkickstarter.app.ui.icon.MultiplatformKickstarterIcons @Composable fun PetsSearchBar( modifier: Modifier = Modifier, - localization: Localization + localization: Localization, ) { var query by remember { mutableStateOf("") } var active by remember { mutableStateOf(false) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Picker.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Picker.kt index 409014a..f7f3118 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Picker.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Picker.kt @@ -30,14 +30,14 @@ import com.multiplatformkickstarter.app.ui.theme.Typography fun Picker( modifier: Modifier, pickerModel: PickerModel, - onClose: () -> Unit + onClose: () -> Unit, ) { Box( modifier = modifier .fillMaxSize() .background(MaterialTheme.colorScheme.scrim) .clickable { onClose.invoke() }, - contentAlignment = Alignment.BottomCenter + contentAlignment = Alignment.BottomCenter, ) { PickerScaffold(pickerModel.title, pickerModel.description, pickerModel.options, onClose) } @@ -48,7 +48,7 @@ internal fun PickerScaffold( title: String, description: String?, options: List, - onClose: () -> Unit + onClose: () -> Unit, ) { Column( modifier = Modifier @@ -73,14 +73,14 @@ internal fun PickerScaffold( text = title, style = Typography.get().headlineSmall, modifier = Modifier - .padding(16.dp) + .padding(16.dp), ) description?.let { Text( text = title, style = Typography.get().bodyMedium, modifier = Modifier - .padding(start = 16.dp) + .padding(start = 16.dp), ) } @@ -103,7 +103,7 @@ fun PickerItem(text: String, icon: ImageVector?, action: () -> Unit) { .fillMaxWidth() .size(60.dp) .padding(start = 16.dp), - horizontalArrangement = Arrangement.Start + horizontalArrangement = Arrangement.Start, ) { icon?.let { Icon( @@ -111,14 +111,14 @@ fun PickerItem(text: String, icon: ImageVector?, action: () -> Unit) { .size(24.dp) .align(Alignment.CenterVertically), imageVector = it, - contentDescription = null // decorative image + contentDescription = null, // decorative image ) Spacer(modifier = Modifier.width(16.dp)) } Text( text = text, style = Typography.get().bodyLarge, - modifier = Modifier.align(Alignment.CenterVertically) + modifier = Modifier.align(Alignment.CenterVertically), ) } } @@ -128,6 +128,11 @@ fun PickerItem(text: String, icon: ImageVector?, action: () -> Unit) { data class PickerModel( val title: String, val description: String?, - val options: List + val options: List, +) + +data class PickerOption( + val text: String, + val icon: ImageVector?, + val action: () -> Unit ) -data class PickerOption(val text: String, val icon: ImageVector?, val action: () -> Unit) diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/RatingBar.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/RatingBar.kt index 97d08c1..d3ba421 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/RatingBar.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/RatingBar.kt @@ -8,12 +8,13 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +@Suppress("FunctionName") @Composable fun RatingBar( modifier: Modifier = Modifier, rating: Double = 0.0, stars: Int = 5, - starsColor: Color = Color.Yellow + starsColor: Color = Color.Yellow, ) { val filledStars = kotlin.math.floor(rating).toInt() val unfilledStars = (stars - kotlin.math.ceil(rating)).toInt() @@ -28,7 +29,7 @@ fun RatingBar( Icon( imageVector = Icons.Outlined.Star, contentDescription = null, - tint = starsColor + tint = starsColor, ) } @@ -36,7 +37,7 @@ fun RatingBar( Icon( imageVector = Icons.Outlined.Star, contentDescription = null, - tint = starsColor + tint = starsColor, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Toast.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Toast.kt index 528bb0f..65db23c 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Toast.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/Toast.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape +//noinspection UsingMaterialAndMaterial3Libraries import androidx.compose.material.Surface import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/TopAppBar.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/TopAppBar.kt index a04a00f..ee3822b 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/TopAppBar.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/components/TopAppBar.kt @@ -49,48 +49,3 @@ fun MultiplatformKickstarterTopAppBar( modifier = modifier ) } - -/** - * Top app bar with action, displayed on the right - */ - -/* -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MyProjectNameTopAppBar( - title: String, - actionIcon: ImageVector, - actionIconContentDescription: String?, - modifier: Modifier = Modifier, - colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(), - onActionClick: () -> Unit = {} -) { - CenterAlignedTopAppBar( - title = { Text(text = title) }, - actions = { - /*IconButton(onClick = onActionClick) { - Icon( - imageVector = actionIcon, - contentDescription = actionIconContentDescription, - tint = MaterialTheme.colorScheme.onSurface - ) - }*/ - }, - colors = colors, - modifier = modifier - ) -} - */ - -/*@OptIn(ExperimentalMaterial3Api::class) -@Preview("Top App Bar") -@Composable -fun MyProjectNameTopAppBarPreview() { - MyProjectNameTopAppBar( - titleRes = R.string.untitled, - navigationIcon = Icons.Default.Search, - navigationIconContentDescription = "Navigation icon", - actionIcon = Icons.Default.MoreVert, - actionIconContentDescription = "Action icon" - ) -}*/ diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/HomeTabScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/HomeTabScreen.kt index 09c87a8..8a38b4b 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/HomeTabScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/HomeTabScreen.kt @@ -135,7 +135,6 @@ class HomeTabScreen : Screen { ) } ) { paddingValues -> - BoxWithConstraints(Modifier.fillMaxSize().padding(paddingValues), propagateMinConstraints = true) { val maxWidth = this.maxWidth @@ -164,7 +163,10 @@ class HomeTabScreen : Screen { } @Composable - fun BannerHeader(viewModel: HomeScreenViewModel, localization: Localization) { + fun BannerHeader( + viewModel: HomeScreenViewModel, + localization: Localization, + ) { Box( modifier = Modifier.fillMaxWidth() ) { @@ -207,7 +209,10 @@ class HomeTabScreen : Screen { } @Composable - fun CategoriesCarousel(viewModel: HomeScreenViewModel, localization: Localization) { + fun CategoriesCarousel( + viewModel: HomeScreenViewModel, + localization: Localization, + ) { Text( text = localization.homeScreenCategoryTitle, style = Typography.get().titleMedium, @@ -240,7 +245,11 @@ class HomeTabScreen : Screen { } @Composable - fun LastSearchCarousel(viewModel: HomeScreenViewModel, localization: Localization, state: HomeScreenState) { + fun LastSearchCarousel( + viewModel: HomeScreenViewModel, + localization: Localization, + state: HomeScreenState, + ) { if (state.lastSearchAds.isNotEmpty()) { Row( modifier = Modifier.fillMaxWidth(), @@ -277,7 +286,12 @@ class HomeTabScreen : Screen { } @Composable - fun NearMeListView(viewModel: HomeScreenViewModel, state: HomeScreenState, localization: Localization, maxWidth: Dp) { + fun NearMeListView( + viewModel: HomeScreenViewModel, + state: HomeScreenState, + localization: Localization, + maxWidth: Dp, + ) { Text( text = localization.homePetsNearYou, style = Typography.get().titleMedium, diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/MainScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/MainScreen.kt index 03f18d6..01db9d8 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/MainScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/MainScreen.kt @@ -45,7 +45,7 @@ fun MainScreenView() { val rootNavigator = LocalNavigator.currentOrThrow TabNavigator( HomeTab, - disposeNestedNavigators = false + disposeNestedNavigators = false, ) { _ -> val rootNavigatorRepository = setupRootNavigator(rootNavigator, LocalTabNavigator.current) val rootSnackbarHostStateRepository = setupRootSnackbarHostState(snackbarHostState) @@ -63,7 +63,7 @@ fun MainScreenView() { TabNavigationItem(InboxTab, rootNavigatorRepository) TabNavigationItem(ProfileTab, rootNavigatorRepository) } - } + }, ) { SlideTransition(LocalNavigator.currentOrThrow) { screen -> screen.Content() @@ -72,7 +72,10 @@ fun MainScreenView() { } } -fun setupRootNavigator(rootNavigator: Navigator, tabNavigator: TabNavigator): RootNavigatorRepository { +fun setupRootNavigator( + rootNavigator: Navigator, + tabNavigator: TabNavigator, +): RootNavigatorRepository { val koin = KoinPlatform.getKoin() return koin.get(null, parameters = { ParametersHolder(listOf(rootNavigator, tabNavigator).toMutableList(), false) }) } @@ -83,7 +86,10 @@ fun setupRootSnackbarHostState(snackbarHostState: SnackbarHostState): RootSnackb } @Composable -private fun RowScope.TabNavigationItem(tab: Tab, rootNavigator: RootNavigatorRepository) { +private fun RowScope.TabNavigationItem( + tab: Tab, + rootNavigator: RootNavigatorRepository, +) { val tabNavigator = LocalTabNavigator.current val currentDestination = tabNavigator.current.key == tab.key @@ -100,10 +106,12 @@ private fun RowScope.TabNavigationItem(tab: Tab, rootNavigator: RootNavigatorRep tab.options.icon?.let { androidx.compose.material3.Icon( painter = it, - contentDescription = tab.options.title + contentDescription = tab.options.title, ) } }, - label = { androidx.compose.material3.Text(tab.options.title) } + label = { + androidx.compose.material3.Text(tab.options.title) + } ) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/OnboardingScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/OnboardingScreen.kt index f6ddaac..d7d20c0 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/OnboardingScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/OnboardingScreen.kt @@ -19,49 +19,69 @@ import com.multiplatformkickstarter.app.ui.components.OnboardingComponent import com.multiplatformkickstarter.app.ui.theme.MultiplatformKickstarterTheme class OnboardingScreen : Screen { - @Composable override fun Content() { val localization = getCurrentLocalization() val navigator = LocalNavigator.currentOrThrow MultiplatformKickstarterTheme { - val onboardingPromoTitle1 = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append(localization.onboardingPromoTitle1) + val onboardingPromoTitle1 = + buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append(localization.onboardingPromoTitle1) + } } - } - val onboardingPromoLine1 = buildAnnotatedString { - append("Welcome to ") - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append("Multiplatform Kickstarter") + val onboardingPromoLine1 = + buildAnnotatedString { + append("Welcome to ") + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append("Multiplatform Kickstarter") + } + append(localization.onboardingPromoLine1) } - append(localization.onboardingPromoLine1) - } - val onboardingPromoTitle2 = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append(localization.onboardingPromoTitle2) + val onboardingPromoTitle2 = + buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append(localization.onboardingPromoTitle2) + } } - } - val onboardingPromoTitle3 = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append(localization.onboardingPromoTitle3) + val onboardingPromoTitle3 = + buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append(localization.onboardingPromoTitle3) + } } - } - val onboardingPromoLine3 = buildAnnotatedString { - append(localization.onboardingPromoLine3) - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append("multiplatformkickstarter.com") + val onboardingPromoLine3 = + buildAnnotatedString { + append(localization.onboardingPromoLine3) + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append("multiplatformkickstarter.com") + } } - } - val carouselItems: List = listOf( - CarouselItem(Res.drawable.mklogo, onboardingPromoTitle1, onboardingPromoLine1, localization.next), - CarouselItem(Res.drawable.features_overview_cuate, onboardingPromoTitle2, localization.onboardingPromoLine2.toAnnotatedString(), localization.next), - CarouselItem(Res.drawable.product_quality_amico, onboardingPromoTitle3, onboardingPromoLine3, localization.close) { navigator.pop() } - ) + val carouselItems: List = + listOf( + CarouselItem( + Res.drawable.mklogo, + onboardingPromoTitle1, + onboardingPromoLine1, + localization.next + ), + CarouselItem( + Res.drawable.features_overview_cuate, + onboardingPromoTitle2, + localization.onboardingPromoLine2.toAnnotatedString(), + localization.next + ), + CarouselItem( + Res.drawable.product_quality_amico, + onboardingPromoTitle3, + onboardingPromoLine3, + localization.close + ) { navigator.pop() } + ) val onboardingComponent = OnboardingComponent(carouselItems) onboardingComponent.DrawCarousel() } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/PetDetailScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/PetDetailScreen.kt index c9e5435..38d9099 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/PetDetailScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/PetDetailScreen.kt @@ -69,7 +69,7 @@ fun PetDetailView(petModel: PetModel, onClose: () -> Unit) { IconButton(onClick = { onClose.invoke() }) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = localization.backButton + contentDescription = localization.backButton, ) } }, @@ -107,13 +107,13 @@ fun PetDetailView(petModel: PetModel, onClose: () -> Unit) { .background(color = MaterialTheme.colorScheme.primaryContainer) .height(250.dp) .fillMaxWidth(), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Icon( modifier = Modifier.size(64.dp), imageVector = MultiplatformKickstarterIcons.Person, contentDescription = "image", - tint = MaterialTheme.colorScheme.onPrimaryContainer + tint = MaterialTheme.colorScheme.onPrimaryContainer, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProTemplateFeatureScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProTemplateFeatureScreen.kt index 659f776..2b59eff 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProTemplateFeatureScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProTemplateFeatureScreen.kt @@ -24,15 +24,16 @@ import com.multiplatformkickstarter.app.resources.Res import com.multiplatformkickstarter.app.resources.mklogo import org.jetbrains.compose.resources.vectorResource +@Suppress("FunctionName") @Composable fun ProTemplateFeature( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { val localization = getCurrentLocalization() Column( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Image( imageVector = vectorResource(Res.drawable.mklogo), @@ -41,27 +42,28 @@ fun ProTemplateFeature( .fillMaxHeight(0.4f) .fillMaxWidth() .padding(start = 24.dp, end = 24.dp), - contentScale = ContentScale.FillWidth + contentScale = ContentScale.FillWidth, ) Text( modifier = Modifier.padding(16.dp), text = localization.proFeatureScreenTitle, style = MaterialTheme.typography.headlineMedium, textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.primary + color = MaterialTheme.colorScheme.primary, ) - val proFeaturesDescription = buildAnnotatedString { - append(localization.proFeatureScreenDescription) - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { - append("multiplatformkickstarter.com") + val proFeaturesDescription = + buildAnnotatedString { + append(localization.proFeatureScreenDescription) + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append("multiplatformkickstarter.com") + } } - } Text( modifier = Modifier.padding(horizontal = 24.dp), text = proFeaturesDescription, style = MaterialTheme.typography.bodyMedium, textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.outline + color = MaterialTheme.colorScheme.outline, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProfileTabScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProfileTabScreen.kt index 32abf9f..cf6933d 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProfileTabScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/ProfileTabScreen.kt @@ -78,7 +78,11 @@ class ProfileTabScreen : Screen { } @Composable - fun ProfileScreenView(viewModel: ProfileViewModel, state: ProfileState, localization: Localization) { + fun ProfileScreenView( + viewModel: ProfileViewModel, + state: ProfileState, + localization: Localization, + ) { val scrollState = rememberScrollState() MultiplatformKickstarterTheme { Column(modifier = Modifier.padding(bottom = 80.dp).verticalScroll(scrollState)) { @@ -89,7 +93,10 @@ class ProfileTabScreen : Screen { } @Composable - fun UserProfileData(state: ProfileState, viewModel: ProfileViewModel) { + fun UserProfileData( + state: ProfileState, + viewModel: ProfileViewModel, + ) { Row( modifier = Modifier .fillMaxWidth() @@ -97,7 +104,7 @@ class ProfileTabScreen : Screen { .clickable { viewModel.onProfileDetailClicked() }, - horizontalArrangement = Arrangement.Start + horizontalArrangement = Arrangement.Start, ) { if (state.image.isEmpty()) { Icon( @@ -105,7 +112,7 @@ class ProfileTabScreen : Screen { .size(64.dp) .padding(4.dp), imageVector = MultiplatformKickstarterIcons.Person, - contentDescription = null + contentDescription = null, ) } else { KamelImage( @@ -130,13 +137,13 @@ class ProfileTabScreen : Screen { .background(color = MaterialTheme.colorScheme.primaryContainer) .height(64.dp) .fillMaxWidth(), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Icon( modifier = Modifier.size(24.dp), imageVector = MultiplatformKickstarterIcons.Person, contentDescription = "image", - tint = MaterialTheme.colorScheme.onPrimaryContainer + tint = MaterialTheme.colorScheme.onPrimaryContainer, ) } } @@ -182,13 +189,34 @@ class ProfileTabScreen : Screen { @Composable fun OptionsList(localization: Localization, viewModel: ProfileViewModel) { Column(modifier = Modifier.fillMaxWidth()) { - PickerItem(localization.profileMyPets, MultiplatformKickstarterIcons.Pets) { viewModel.onMyPetsClicked() } - PickerItem(localization.profileAccountSettings, MultiplatformKickstarterIcons.Settings) { viewModel.onProfileAccountSettingsClicked() } - PickerItem(localization.profileSettings, MultiplatformKickstarterIcons.Settings) { viewModel.onProfileSettingsClicked() } - PickerItem(localization.profileBlog, MultiplatformKickstarterIcons.Blog) { viewModel.onBlogClicked() } - PickerItem(localization.profileTermsAndConditions, MultiplatformKickstarterIcons.Info) { viewModel.onTermsAndConditionsClicked() } - PickerItem(localization.profileHelp, MultiplatformKickstarterIcons.Help) { viewModel.onHelpClicked() } - PickerItem(localization.profileCloseSession, MultiplatformKickstarterIcons.Exit) { viewModel.onCloseSessionClicked() } + PickerItem( + localization.profileMyPets, + MultiplatformKickstarterIcons.Pets, + ) { viewModel.onMyPetsClicked() } + PickerItem( + localization.profileAccountSettings, + MultiplatformKickstarterIcons.Settings, + ) { viewModel.onProfileAccountSettingsClicked() } + PickerItem( + localization.profileSettings, + MultiplatformKickstarterIcons.Settings, + ) { viewModel.onProfileSettingsClicked() } + PickerItem( + localization.profileBlog, + MultiplatformKickstarterIcons.Blog, + ) { viewModel.onBlogClicked() } + PickerItem( + localization.profileTermsAndConditions, + MultiplatformKickstarterIcons.Info, + ) { viewModel.onTermsAndConditionsClicked() } + PickerItem( + localization.profileHelp, + MultiplatformKickstarterIcons.Help, + ) { viewModel.onHelpClicked() } + PickerItem( + localization.profileCloseSession, + MultiplatformKickstarterIcons.Exit, + ) { viewModel.onCloseSessionClicked() } } } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/SearchListingScreen.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/SearchListingScreen.kt index f85b643..28b8326 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/SearchListingScreen.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/SearchListingScreen.kt @@ -57,7 +57,15 @@ class SearchListingScreen( val navigator = LocalNavigator.currentOrThrow val viewModel = koinScreenModel( - parameters = { ParametersHolder(listOf(searchId, petCategory, navigator).toMutableList(), false) } + parameters = { + ParametersHolder( + listOf( + searchId, + petCategory, + navigator + ).toMutableList(), false + ) + } ) DisposableEffect(key) { @@ -74,7 +82,11 @@ class SearchListingScreen( } @Composable - private fun SetupSideEffects(viewModel: SearchListingViewModel, snackbarHostState: SnackbarHostState, localization: Localization) { + private fun SetupSideEffects( + viewModel: SearchListingViewModel, + snackbarHostState: SnackbarHostState, + localization: Localization + ) { val coroutineScope = rememberCoroutineScope() val sideEffects = viewModel.sideEffects.collectAsState(SearchListingSideEffects.Initial) sideEffects.value.apply { @@ -86,6 +98,7 @@ class SearchListingScreen( snackbarHostState.showSnackbar(localization.genericFailedDefaultMessage) } } + SearchListingSideEffects.OnNoResults -> {} } } @@ -109,37 +122,39 @@ class SearchListingScreen( IconButton(onClick = { onClose.invoke() }) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = localization.backButton + contentDescription = localization.backButton, ) } }, title = { Text( text = topBarTitle, - style = Typography.get().titleMedium + style = Typography.get().titleMedium, ) }, - colors = TopAppBarDefaults.mediumTopAppBarColors( - containerColor = MaterialTheme.colorScheme.background - ), + colors = + TopAppBarDefaults.mediumTopAppBarColors( + containerColor = MaterialTheme.colorScheme.background, + ), actions = { IconButton(onClick = { }) { Icon( imageVector = MultiplatformKickstarterIcons.Filter, - contentDescription = localization.backLabel + contentDescription = localization.backLabel, ) } - } + }, ) } ) { Column( - modifier = Modifier - .fillMaxSize() - .padding(it) - .padding(bottom = 16.dp) - .verticalScroll(scrollState) - .background(MaterialTheme.colorScheme.background) + modifier = + Modifier + .fillMaxSize() + .padding(it) + .padding(bottom = 16.dp) + .verticalScroll(scrollState) + .background(MaterialTheme.colorScheme.background), ) { if (state.pets.isNotEmpty()) { state.pets.map { petModel -> diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/HomeScreenViewModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/HomeScreenViewModel.kt index 1051789..fd3a04f 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/HomeScreenViewModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/HomeScreenViewModel.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalTime::class) + package com.multiplatformkickstarter.app.ui.screens.viewmodel import cafe.adriel.voyager.core.model.ScreenModel @@ -30,9 +32,10 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch -import kotlinx.datetime.Clock import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime +import kotlin.time.Clock +import kotlin.time.ExperimentalTime private const val ONBOARDING_VIEWED_KEY = "onboarding_viewed_key" @@ -46,20 +49,21 @@ class HomeScreenViewModel( private val rootNavigatorRepository: RootNavigatorRepository, private val lastSearchesRepository: LastSearchesRepository, private val globalAppSettingsRepository: GlobalAppSettingsRepository, - private val settings: Settings + private val settings: Settings, ) : ScreenModel { private val _sideEffects = Channel() val sideEffects: Flow = _sideEffects.receiveAsFlow() - private val _state = MutableStateFlow( - HomeScreenState( - userName = null, - greeting = localization.homeScreenSignUpLogin, - header = getMainHeader(null), - nearMeAds = emptyList(), - lastSearchAds = emptyList(), - currentLanguage = AvailableLanguages.EN + private val _state = + MutableStateFlow( + HomeScreenState( + userName = null, + greeting = localization.homeScreenSignUpLogin, + header = getMainHeader(null), + nearMeAds = emptyList(), + lastSearchAds = emptyList(), + currentLanguage = AvailableLanguages.EN, + ) ) - ) val state: StateFlow = _state.asStateFlow() private val debugComponent = getDebug() @@ -128,14 +132,15 @@ class HomeScreenViewModel( .onSuccess { _state.value = _state.value.copy(nearMeAds = it) } - _state.value = _state.value.copy( - userName = profileRepository.getName(), - greeting = getGreeting(), - header = getMainHeader(profileRepository.getName()), - nearMeAds = _state.value.nearMeAds, - lastSearchAds = _state.value.lastSearchAds, - currentLanguage = globalAppSettingsRepository.getCurrentLanguage() - ) + _state.value = + _state.value.copy( + userName = profileRepository.getName(), + greeting = getGreeting(), + header = getMainHeader(profileRepository.getName()), + nearMeAds = _state.value.nearMeAds, + lastSearchAds = _state.value.lastSearchAds, + currentLanguage = globalAppSettingsRepository.getCurrentLanguage(), + ) } } @@ -154,7 +159,7 @@ data class HomeScreenState( val header: String, val nearMeAds: List, val lastSearchAds: List, - val currentLanguage: AvailableLanguages + val currentLanguage: AvailableLanguages, ) sealed class HomeScreenSideEffects diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/ProfileViewModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/ProfileViewModel.kt index 564c829..79ecb85 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/ProfileViewModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/ProfileViewModel.kt @@ -22,7 +22,7 @@ class ProfileViewModel( private var navigator: Navigator, private val profileRepository: ProfileRepository, private val sessionRepository: SessionRepository, - private val rootNavigatorRepository: RootNavigatorRepository + private val rootNavigatorRepository: RootNavigatorRepository, ) : ScreenModel { private val _state = MutableStateFlow(ProfileState("", "", "", null, 0.0, false)) val state = _state.asStateFlow() @@ -67,14 +67,15 @@ class ProfileViewModel( fun onStarted(navigator: Navigator) { this.navigator = navigator screenModelScope.launch { - _state.value = ProfileState( - name = profileRepository.getName(), - description = profileRepository.getDescription(), - image = profileRepository.getImage(), - location = profileRepository.getLocation(), - rating = profileRepository.getRating(), - isLoggedIn = sessionRepository.isLoggedIn() - ) + _state.value = + ProfileState( + name = profileRepository.getName(), + description = profileRepository.getDescription(), + image = profileRepository.getImage(), + location = profileRepository.getLocation(), + rating = profileRepository.getRating(), + isLoggedIn = sessionRepository.isLoggedIn() + ) } } @@ -94,6 +95,8 @@ data class ProfileState( sealed class ProfileSideEffects { data object Initial : ProfileSideEffects() + data object OnSignedUp : ProfileSideEffects() + data object OnSignUpError : ProfileSideEffects() } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/SearchListingViewModel.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/SearchListingViewModel.kt index 29daf40..526313c 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/SearchListingViewModel.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/screens/viewmodel/SearchListingViewModel.kt @@ -62,12 +62,15 @@ class SearchListingViewModel( data class SearchListingState( val searchId: Int? = null, val petCategory: PetCategory? = null, - val pets: List + val pets: List, ) sealed class SearchListingSideEffects { data object Initial : SearchListingSideEffects() + data class OnLoaded(val pets: List) : SearchListingSideEffects() + data object OnNoResults : SearchListingSideEffects() + data object OnLoadError : SearchListingSideEffects() } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Background.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Background.kt index 7f3fd70..e4e571f 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Background.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Background.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp @Immutable data class BackgroundTheme( val color: Color = Color.Unspecified, - val tonalElevation: Dp = Dp.Unspecified + val tonalElevation: Dp = Dp.Unspecified, ) /** @@ -40,6 +40,7 @@ val LocalBackgroundTheme = staticCompositionLocalOf { BackgroundTheme() } * @param modifier Modifier to be applied to the background. * @param content The background content. */ +@Suppress("FunctionName") @Composable fun MultiplatformKickstarterBackground( modifier: Modifier = Modifier, @@ -83,39 +84,36 @@ fun MultiplatformKickstarterGradientBackground( .drawWithCache { // Compute the start and end coordinates such that the gradients are angled 11.06 // degrees off the vertical axis - /*val offset = size.height * tan( - Math - .toRadians(11.06) - .toFloat() - ) - */ val offset = size.height val start = Offset(size.width / 2 + offset / 2, 0f) val end = Offset(size.width / 2 - offset / 2, size.height) // Create the top gradient that fades out after the halfway point vertically - val topGradient = Brush.linearGradient( - 0f to if (currentTopColor == Color.Unspecified) { - Color.Transparent - } else { - currentTopColor - }, - 0.724f to Color.Transparent, - start = start, - end = end - ) + val topGradient = + Brush.linearGradient( + 0f to + if (currentTopColor == Color.Unspecified) { + Color.Transparent + } else { + currentTopColor + }, + 0.724f to Color.Transparent, + start = start, + end = end, + ) // Create the bottom gradient that fades in before the halfway point vertically - val bottomGradient = Brush.linearGradient( - 0.2552f to Color.Transparent, - 1f to if (currentBottomColor == Color.Unspecified) { - Color.Transparent - } else { - currentBottomColor - }, - start = start, - end = end - ) + val bottomGradient = + Brush.linearGradient( + 0.2552f to Color.Transparent, + 1f to if (currentBottomColor == Color.Unspecified) { + Color.Transparent + } else { + currentBottomColor + }, + start = start, + end = end, + ) onDrawBehind { // There is overlap here, so order is important @@ -133,10 +131,9 @@ fun MultiplatformKickstarterGradientBackground( * Multipreview annotation that represents light and dark themes. Add this annotation to a * composable to render the both themes. */ -// @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, name = "Light theme") -// @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, name = "Dark theme") annotation class ThemePreviews +@Suppress("FunctionName") @ThemePreviews @Composable fun BackgroundDefault() { @@ -145,6 +142,7 @@ fun BackgroundDefault() { } } +@Suppress("FunctionName") @ThemePreviews @Composable fun BackgroundDynamic() { @@ -153,6 +151,7 @@ fun BackgroundDynamic() { } } +@Suppress("FunctionName") @ThemePreviews @Composable fun GradientBackgroundDefault() { @@ -161,6 +160,7 @@ fun GradientBackgroundDefault() { } } +@Suppress("FunctionName") @ThemePreviews @Composable fun GradientBackgroundDynamic() { diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Fonts.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Fonts.kt index 92e26ea..4e1af10 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Fonts.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Fonts.kt @@ -8,36 +8,37 @@ import com.multiplatformkickstarter.app.platform.font object Fonts { @Composable - fun poppinsFamily() = FontFamily( - font( - "Poppins Light", - "poppins_light", - FontWeight.Light, - FontStyle.Normal - ), - font( - "Poppins Regular", - "poppins_regular", - FontWeight.Normal, - FontStyle.Normal - ), - font( - "Poppins Italic", - "poppins_italic", - FontWeight.Normal, - FontStyle.Italic - ), - font( - "Poppins Medium", - "poppins_medium", - FontWeight.Medium, - FontStyle.Normal - ), - font( - "Poppins Bold", - "poppins_bold", - FontWeight.Bold, - FontStyle.Normal + fun poppinsFamily() = + FontFamily( + font( + "Poppins Light", + "poppins_light", + FontWeight.Light, + FontStyle.Normal, + ), + font( + "Poppins Regular", + "poppins_regular", + FontWeight.Normal, + FontStyle.Normal, + ), + font( + "Poppins Italic", + "poppins_italic", + FontWeight.Normal, + FontStyle.Italic, + ), + font( + "Poppins Medium", + "poppins_medium", + FontWeight.Medium, + FontStyle.Normal, + ), + font( + "Poppins Bold", + "poppins_bold", + FontWeight.Bold, + FontStyle.Normal, + ) ) - ) } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Gradient.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Gradient.kt index bcfe41c..6ea74cf 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Gradient.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Gradient.kt @@ -28,7 +28,7 @@ data class GradientColors( val primary: Color = Color.Unspecified, val secondary: Color = Color.Unspecified, val tertiary: Color = Color.Unspecified, - val neutral: Color = Color.Unspecified + val neutral: Color = Color.Unspecified, ) /** diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Shape.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Shape.kt index 5be8eac..889d947 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Shape.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/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/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Theme.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Theme.kt index 7bb41e6..0628db0 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Theme.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Theme.kt @@ -11,86 +11,89 @@ import androidx.compose.ui.unit.dp /** * Light default theme color scheme */ -// @VisibleForTesting -val LightDefaultColorScheme = lightColorScheme( - primary = lightPrimary, - onPrimary = lightOnPrimary, - primaryContainer = lightPrimaryContainer, - onPrimaryContainer = lightOnPrimaryContainer, - inversePrimary = lightPrimaryInverse, - secondary = lightSecondary, - onSecondary = lightOnSecondary, - secondaryContainer = lightSecondaryContainer, - onSecondaryContainer = lightOnSecondaryContainer, - tertiary = lightTertiary, - onTertiary = lightOnTertiary, - tertiaryContainer = lightTertiaryContainer, - onTertiaryContainer = lightOnTertiaryContainer, - error = lightError, - onError = lightOnError, - errorContainer = lightErrorContainer, - onErrorContainer = lightOnErrorContainer, - background = lightBackground, - onBackground = lightOnBackground, - surface = lightSurface, - onSurface = lightOnSurface, - inverseSurface = lightInverseSurface, - inverseOnSurface = lightInverseOnSurface, - surfaceVariant = lightSurfaceVariant, - onSurfaceVariant = lightOnSurfaceVariant, - outline = lightOutline, - scrim = scrimColor -) +val LightDefaultColorScheme = + lightColorScheme( + primary = lightPrimary, + onPrimary = lightOnPrimary, + primaryContainer = lightPrimaryContainer, + onPrimaryContainer = lightOnPrimaryContainer, + inversePrimary = lightPrimaryInverse, + secondary = lightSecondary, + onSecondary = lightOnSecondary, + secondaryContainer = lightSecondaryContainer, + onSecondaryContainer = lightOnSecondaryContainer, + tertiary = lightTertiary, + onTertiary = lightOnTertiary, + tertiaryContainer = lightTertiaryContainer, + onTertiaryContainer = lightOnTertiaryContainer, + error = lightError, + onError = lightOnError, + errorContainer = lightErrorContainer, + onErrorContainer = lightOnErrorContainer, + background = lightBackground, + onBackground = lightOnBackground, + surface = lightSurface, + onSurface = lightOnSurface, + inverseSurface = lightInverseSurface, + inverseOnSurface = lightInverseOnSurface, + surfaceVariant = lightSurfaceVariant, + onSurfaceVariant = lightOnSurfaceVariant, + outline = lightOutline, + scrim = scrimColor, + ) /** * Dark default theme color scheme */ // @VisibleForTesting -val DarkDefaultColorScheme = darkColorScheme( - primary = darkPrimary, - onPrimary = darkOnPrimary, - primaryContainer = darkPrimaryContainer, - onPrimaryContainer = darkOnPrimaryContainer, - inversePrimary = darkPrimaryInverse, - secondary = darkSecondary, - onSecondary = darkOnSecondary, - secondaryContainer = darkSecondaryContainer, - onSecondaryContainer = darkOnSecondaryContainer, - tertiary = darkTertiary, - onTertiary = darkOnTertiary, - tertiaryContainer = darkTertiaryContainer, - onTertiaryContainer = darkOnTertiaryContainer, - error = darkError, - onError = darkOnError, - errorContainer = darkErrorContainer, - onErrorContainer = darkOnErrorContainer, - background = darkBackground, - onBackground = darkOnBackground, - surface = darkSurface, - onSurface = darkOnSurface, - inverseSurface = darkInverseSurface, - inverseOnSurface = darkInverseOnSurface, - surfaceVariant = darkSurfaceVariant, - onSurfaceVariant = darkOnSurfaceVariant, - outline = darkOutline, - scrim = scrimColor -) +val DarkDefaultColorScheme = + darkColorScheme( + primary = darkPrimary, + onPrimary = darkOnPrimary, + primaryContainer = darkPrimaryContainer, + onPrimaryContainer = darkOnPrimaryContainer, + inversePrimary = darkPrimaryInverse, + secondary = darkSecondary, + onSecondary = darkOnSecondary, + secondaryContainer = darkSecondaryContainer, + onSecondaryContainer = darkOnSecondaryContainer, + tertiary = darkTertiary, + onTertiary = darkOnTertiary, + tertiaryContainer = darkTertiaryContainer, + onTertiaryContainer = darkOnTertiaryContainer, + error = darkError, + onError = darkOnError, + errorContainer = darkErrorContainer, + onErrorContainer = darkOnErrorContainer, + background = darkBackground, + onBackground = darkOnBackground, + surface = darkSurface, + onSurface = darkOnSurface, + inverseSurface = darkInverseSurface, + inverseOnSurface = darkInverseOnSurface, + surfaceVariant = darkSurfaceVariant, + onSurfaceVariant = darkOnSurfaceVariant, + outline = darkOutline, + scrim = scrimColor, + ) /** * Light default gradient colors */ -val LightDefaultGradientColors = GradientColors( - primary = lightPrimary, - secondary = lightSecondary, - tertiary = lightTertiary, - neutral = lightOnPrimary -) +val LightDefaultGradientColors = + GradientColors( + primary = lightPrimary, + secondary = lightSecondary, + tertiary = lightTertiary, + neutral = lightOnPrimary, + ) /** * Now in Android theme. * * @param darkTheme Whether the theme should use a dark color scheme (follows system by default). */ +@Suppress("FunctionName") @Composable fun MultiplatformKickstarterTheme( darkTheme: Boolean = isSystemInDarkTheme(), @@ -115,30 +118,32 @@ fun MultiplatformKickstarterTheme( internal fun MultiplatformKickstarterTheme( darkTheme: Boolean = isSystemInDarkTheme(), disableDynamicTheming: Boolean, - content: @Composable () -> Unit + content: @Composable () -> Unit, ) { val colorScheme = if (darkTheme) DarkDefaultColorScheme else LightDefaultColorScheme val defaultGradientColors = GradientColors() - val gradientColors = if (!disableDynamicTheming) { - defaultGradientColors - } else { - if (darkTheme) defaultGradientColors else LightDefaultGradientColors - } + val gradientColors = + if (!disableDynamicTheming) { + defaultGradientColors + } else { + if (darkTheme) defaultGradientColors else LightDefaultGradientColors + } - val defaultBackgroundTheme = BackgroundTheme( - color = colorScheme.surface, - tonalElevation = 2.dp - ) + val defaultBackgroundTheme = + BackgroundTheme( + color = colorScheme.surface, + tonalElevation = 2.dp, + ) CompositionLocalProvider( LocalGradientColors provides gradientColors, - LocalBackgroundTheme provides defaultBackgroundTheme + LocalBackgroundTheme provides defaultBackgroundTheme, ) { MaterialTheme( colorScheme = colorScheme, typography = Typography.get(), - content = content + content = content, ) } } diff --git a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Typography.kt b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Typography.kt index 78000d8..6c6a0aa 100644 --- a/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Typography.kt +++ b/shared/src/commonMain/kotlin/com/multiplatformkickstarter/app/ui/theme/Typography.kt @@ -7,104 +7,120 @@ import androidx.compose.ui.unit.sp object Typography { @Composable - fun get() = androidx.compose.material3.Typography( - displayLarge = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 57.sp, - lineHeight = 64.sp, - letterSpacing = (-0.25).sp, - fontFamily = Fonts.poppinsFamily() - ), - displayMedium = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 45.sp, - lineHeight = 52.sp, - fontFamily = Fonts.poppinsFamily() - ), - displaySmall = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 36.sp, - lineHeight = 44.sp, - fontFamily = Fonts.poppinsFamily() - ), - headlineLarge = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 32.sp, - lineHeight = 40.sp, - fontFamily = Fonts.poppinsFamily() - ), - headlineMedium = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 28.sp, - lineHeight = 36.sp, - fontFamily = Fonts.poppinsFamily() - ), - headlineSmall = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 24.sp, - lineHeight = 32.sp, - fontFamily = Fonts.poppinsFamily() - ), - titleLarge = TextStyle( - fontWeight = FontWeight.W700, - fontSize = 22.sp, - lineHeight = 28.sp, - fontFamily = Fonts.poppinsFamily() - ), - titleMedium = TextStyle( - fontWeight = FontWeight.W700, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.1.sp, - fontFamily = Fonts.poppinsFamily() - ), - titleSmall = TextStyle( - fontWeight = FontWeight.W500, - fontSize = 14.sp, - lineHeight = 20.sp, - letterSpacing = 0.1.sp, - fontFamily = Fonts.poppinsFamily() - ), - bodyLarge = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp, - fontFamily = Fonts.poppinsFamily() - ), - bodyMedium = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 14.sp, - lineHeight = 20.sp, - letterSpacing = 0.25.sp, - fontFamily = Fonts.poppinsFamily() - ), - bodySmall = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 12.sp, - lineHeight = 16.sp, - letterSpacing = 0.4.sp, - fontFamily = Fonts.poppinsFamily() - ), - labelLarge = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 14.sp, - lineHeight = 20.sp, - letterSpacing = 0.1.sp, - fontFamily = Fonts.poppinsFamily() - ), - labelMedium = TextStyle( - fontWeight = FontWeight.W400, - fontSize = 12.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp, - fontFamily = Fonts.poppinsFamily() - ), - labelSmall = TextStyle( - fontFamily = Fonts.poppinsFamily(), - fontWeight = FontWeight.W500, - fontSize = 10.sp, - lineHeight = 16.sp + fun get() = + androidx.compose.material3.Typography( + displayLarge = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 57.sp, + lineHeight = 64.sp, + letterSpacing = (-0.25).sp, + fontFamily = Fonts.poppinsFamily(), + ), + displayMedium = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 45.sp, + lineHeight = 52.sp, + fontFamily = Fonts.poppinsFamily(), + ), + displaySmall = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 36.sp, + lineHeight = 44.sp, + fontFamily = Fonts.poppinsFamily(), + ), + headlineLarge = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 32.sp, + lineHeight = 40.sp, + fontFamily = Fonts.poppinsFamily(), + ), + headlineMedium = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 28.sp, + lineHeight = 36.sp, + fontFamily = Fonts.poppinsFamily(), + ), + headlineSmall = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 24.sp, + lineHeight = 32.sp, + fontFamily = Fonts.poppinsFamily(), + ), + titleLarge = + TextStyle( + fontWeight = FontWeight.W700, + fontSize = 22.sp, + lineHeight = 28.sp, + fontFamily = Fonts.poppinsFamily(), + ), + titleMedium = + TextStyle( + fontWeight = FontWeight.W700, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.1.sp, + fontFamily = Fonts.poppinsFamily(), + ), + titleSmall = + TextStyle( + fontWeight = FontWeight.W500, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.1.sp, + fontFamily = Fonts.poppinsFamily(), + ), + bodyLarge = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp, + fontFamily = Fonts.poppinsFamily(), + ), + bodyMedium = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.25.sp, + fontFamily = Fonts.poppinsFamily(), + ), + bodySmall = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.4.sp, + fontFamily = Fonts.poppinsFamily(), + ), + labelLarge = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.1.sp, + fontFamily = Fonts.poppinsFamily(), + ), + labelMedium = + TextStyle( + fontWeight = FontWeight.W400, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp, + fontFamily = Fonts.poppinsFamily(), + ), + labelSmall = + TextStyle( + fontFamily = Fonts.poppinsFamily(), + fontWeight = FontWeight.W500, + fontSize = 10.sp, + lineHeight = 16.sp, + ) ) - ) } diff --git a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.ios.kt b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.ios.kt index 57cb986..2b5bd32 100644 --- a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.ios.kt +++ b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.ios.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable actual fun getCurrentLanguage(): AvailableLanguages = AvailableLanguages.EN +@Suppress("FunctionName") @Composable actual fun SetLanguage(language: AvailableLanguages) { } diff --git a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/main.ios.kt b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/main.ios.kt index da255b0..3f4d900 100644 --- a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/main.ios.kt +++ b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/main.ios.kt @@ -1,13 +1,11 @@ -/* ktlint-disable */ +@file:Suppress("ktlint:standard:filename") package com.multiplatformkickstarter.app - import androidx.compose.ui.window.ComposeUIViewController import platform.UIKit.UIViewController -fun homeScreenViewController(): UIViewController = ComposeUIViewController { - MainApp() -} - -/* ktlint-disable */ +fun homeScreenViewController(): UIViewController = + ComposeUIViewController { + MainApp() + } diff --git a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt index 4ed9dd8..ca2a028 100644 --- a/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt +++ b/shared/src/iosMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.kt @@ -15,11 +15,17 @@ private val cache: MutableMap = mutableMapOf() @OptIn(InternalResourceApi::class) @Composable -actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font { +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font { return cache.getOrPut(res) { - val byteArray = runBlocking { - readResourceBytes("font/$res.ttf") - } + val byteArray = + runBlocking { + readResourceBytes("font/$res.ttf") + } androidx.compose.ui.text.platform.Font(res, byteArray, weight, style) } } diff --git a/shared/src/iosTest/kotlin/com/multiplatformkickstarter/app/IosTest.kt b/shared/src/iosTest/kotlin/com/multiplatformkickstarter/app/IosTest.kt index 92a88b5..baa641f 100644 --- a/shared/src/iosTest/kotlin/com/multiplatformkickstarter/app/IosTest.kt +++ b/shared/src/iosTest/kotlin/com/multiplatformkickstarter/app/IosTest.kt @@ -3,7 +3,6 @@ package com.multiplatformkickstarter.app import kotlin.test.Test class IosTest { - @Test fun testExample() { // assertTrue(Greeting().greet().contains("iOS"), "Check iOS is mentioned") diff --git a/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.jvm.kt b/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.jvm.kt index 57cb986..2b5bd32 100644 --- a/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.jvm.kt +++ b/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/localization/Localization.jvm.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable actual fun getCurrentLanguage(): AvailableLanguages = AvailableLanguages.EN +@Suppress("FunctionName") @Composable actual fun SetLanguage(language: AvailableLanguages) { } diff --git a/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.jvm.kt b/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.jvm.kt index deee0f6..f83491d 100644 --- a/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.jvm.kt +++ b/shared/src/jvmMain/kotlin/com/multiplatformkickstarter/app/platform/Resources.jvm.kt @@ -12,11 +12,17 @@ private val cache: MutableMap = mutableMapOf() @OptIn(InternalResourceApi::class) @Composable -actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font { +actual fun font( + name: String, + res: String, + weight: FontWeight, + style: FontStyle, +): Font { return cache.getOrPut(res) { - val byteArray = runBlocking { - readResourceBytes("font/$res.ttf") - } + val byteArray = + runBlocking { + readResourceBytes("font/$res.ttf") + } androidx.compose.ui.text.platform.Font(res, byteArray, weight, style) } }