diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 75cf723..f5e8b61 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v2 - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7e7be7b..624e7e7 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,10 +11,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v2 - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' diff --git a/README.md b/README.md index 6a09ff1..1ba257b 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,14 @@ -# Bob -- The Handy Feedback App +This is a Kotlin Multiplatform project targeting Android, iOS. -This project is a simple Kotlin Multiplatform Application that allows users to enter free-text and -submit the content to a server over HTTP. It also includes a form with sentiment selection and -displays a Snackbar whenever the submit button is pressed. +* `/composeApp` is for code that will be shared across your Compose Multiplatform applications. + It contains several subfolders: + - `commonMain` is for code that’s common for all targets. + - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. + For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, + `iosMain` would be the right folder for such calls. -## Features +* `/iosApp` contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, + you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project. -- Free-text input form -- Sentiment selection using FilterChips -- Submit content to a server using Retrofit -- Display Snackbar on form submission -## Technologies Used - -- Kotlin -- Jetpack Compose -- Retrofit -- Gradle - -## Getting Started - -### Installation - -1. Download the latest release from - the [releases page](https://git.brmartin.co.uk/bob/mobile-application/releases) -2. Install the application following the on-screen instructions. - -### Usage - -1. Run the application on an Android emulator or a physical device. -2. Select a sentiment using the FilterChips. -3. Enter your text in the provided text field. -4. Press the submit button to send the content to the server. - -### Project Structure - -- `composeApp/src/commonMain/kotlin/uk/sky/bob/application/App.kt`: Main Compose UI and form - submission logic. +Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)… \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/uk/sky/bob/application/App.kt b/composeApp/src/commonMain/kotlin/uk/sky/bob/application/App.kt index 4793c10..89b542e 100644 --- a/composeApp/src/commonMain/kotlin/uk/sky/bob/application/App.kt +++ b/composeApp/src/commonMain/kotlin/uk/sky/bob/application/App.kt @@ -1,38 +1,25 @@ package uk.sky.bob.application -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.Button -import androidx.compose.material.ChipDefaults import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.FilterChip -import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.TextField -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Send -import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import org.jetbrains.compose.ui.tooling.preview.Preview @OptIn(ExperimentalMaterialApi::class) @@ -40,60 +27,38 @@ import org.jetbrains.compose.ui.tooling.preview.Preview @Preview fun App() { MaterialTheme { - val scaffoldState = rememberScaffoldState() - val scope = rememberCoroutineScope() + Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Row { + val state = remember { mutableStateOf(Sentiment.HAPPY) } + for (emotion in Sentiment.entries) { + FilterChip( + onClick = { state.value = emotion }, + selected = state.value == emotion, + modifier = Modifier.padding(8.dp), + leadingIcon = { Text(emotion.leadingIcon) }, + ) { + Text(emotion.friendlyName) + } + } + } - Scaffold(scaffoldState = scaffoldState) { - Box( - modifier = Modifier.fillMaxHeight(), - contentAlignment = Alignment.Center, - ) { - Column( - Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - val sentiment = remember { mutableStateOf(Sentiment.HAPPY) } - var comment by rememberSaveable(stateSaver = TextFieldValue.Saver) { - mutableStateOf( - TextFieldValue("") - ) - } - Row(modifier = Modifier.padding(8.dp)) { - for (emotion in Sentiment.entries) { - FilterChip( - onClick = { sentiment.value = emotion }, - selected = sentiment.value == emotion, - modifier = Modifier.padding(8.dp), - leadingIcon = { Text(emotion.leadingIcon, fontSize = 20.sp) }, - colors = ChipDefaults.outlinedFilterChipColors(), - border = ChipDefaults.outlinedBorder, - ) { - Text(emotion.friendlyName, fontSize = 20.sp) - } - } - } + Row { + var text by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue("") + ) + } + TextField( + value = text, + onValueChange = { text = it }, + label = { Text("Your comment") }, + maxLines = 3, + ) + } - Row(modifier = Modifier.padding(8.dp)) { - TextField( - value = comment, - onValueChange = { comment = it }, - label = { Text("Your comment") }, - modifier = Modifier.height(100.dp).fillMaxWidth().padding(8.dp), - ) - } - - Row(modifier = Modifier.padding(8.dp)) { - Button(onClick = { - sentiment.value = Sentiment.HAPPY - comment = TextFieldValue("") - scope.launch { - delay(1000) - scaffoldState.snackbarHostState.showSnackbar("Feedback sent") - } - }, modifier = Modifier.padding(8.dp)) { - Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "Send") - } - } + Row { + Button(onClick = { /* Handle submit */ }) { + Text("Submit") } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1e888c6..d9ed41f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,19 @@ [versions] -agp = "8.10.1" -android-compileSdk = "35" +agp = "8.5.2" +android-compileSdk = "34" android-minSdk = "24" android-targetSdk = "34" -androidx-activityCompose = "1.10.1" -androidx-appcompat = "1.7.1" -androidx-constraintlayout = "2.2.1" -androidx-core-ktx = "1.16.0" +androidx-activityCompose = "1.9.3" +androidx-appcompat = "1.7.0" +androidx-constraintlayout = "2.2.0" +androidx-core-ktx = "1.15.0" androidx-espresso-core = "3.6.1" -androidx-lifecycle = "2.9.1" +androidx-lifecycle = "2.8.4" androidx-material = "1.12.0" androidx-test-junit = "1.2.1" -compose-multiplatform = "1.7.3" +compose-multiplatform = "1.7.0" junit = "4.13.2" -kotlin = "2.1.21" +kotlin = "2.1.0" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ff23a68..09523c0 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.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 7190a60..0000000 --- a/renovate.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json" -}