Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JetPack Compose #42

Draft
wants to merge 37 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
68c1dbb
Add https://mrmans0n.github.io/compose-rules/.
jg210 Mar 29, 2024
3123acf
Add JetPack Compose dependencies and config.
jg210 Mar 29, 2024
a9fe128
Start to reimplement OnboardingActivity using Jetpack Compose.
jg210 May 3, 2024
3ece853
TODO
jg210 May 3, 2024
4ae64a5
Add Switch for onboarding text agreement.
jg210 May 3, 2024
712e06f
Scale in/out animation for FloatingActionButton.
jg210 May 3, 2024
8c16184
Add WebView for onboarding text.
jg210 May 3, 2024
39933ce
Remove unused onboarding.xml.
jg210 May 3, 2024
e823f1b
Suppress detekt warning about Composable function names that start wi…
jg210 May 3, 2024
9c5c40f
TODO
jg210 May 3, 2024
466f76d
Add back code that delays showing rest of onboarding UI until the Web…
jg210 May 6, 2024
c5bc3ee
Code formatting.
jg210 May 6, 2024
88df056
Indent onboarding accept Switch.
jg210 May 6, 2024
5c4e5cc
Change AboutActivity to JetPack compose.
jg210 May 6, 2024
f216387
detekt wants reusable Composible functions to have modifier. Avoid by…
jg210 May 6, 2024
efa820a
Refactor AboutActivity About component.
jg210 May 7, 2024
b02f6ee
Remove about.xml layout.
jg210 May 7, 2024
5409169
TODO
jg210 May 7, 2024
39ca679
Remove unused imports.
jg210 May 7, 2024
c462aea
TODO
jg210 May 9, 2024
f038f55
Partial attempt at using https://github.com/jaredsburrows/gradle-lice…
jg210 May 9, 2024
bb0832c
Revert "Partial attempt at using https://github.com/jaredsburrows/gra…
jg210 May 9, 2024
025cbf6
Replace com.google.android.gms:play-services-oss-licenses with https:…
jg210 May 29, 2024
f498540
TODO
jg210 May 29, 2024
444a03a
Remove unused imports from LicencesActivity.
jg210 May 29, 2024
ea58ab3
Start to convert MainActivity to Jetpack Compose.
jg210 May 30, 2024
ebb6bda
Show HorizontalPager pages based on images LiveData. No images or fac…
jg210 May 31, 2024
17a0868
Refactor MainActivity Floating Action Button code.
jg210 May 31, 2024
97a9652
Only show AddImage page if there are no images.
jg210 May 31, 2024
2395536
Reimplement photo taking.
jg210 Jun 5, 2024
45ef562
Refactor photo taking code into own Composable.
jg210 Jun 5, 2024
d192431
Need to create imagesDir.
jg210 Jun 5, 2024
7d2550f
Remove obsolete commented out code.
jg210 Jun 5, 2024
d4c5725
Centre align merged image text.
jg210 Jun 5, 2024
d53c08b
Workaround for out-of-range page if add image when on merged image pa…
jg210 Jun 5, 2024
2f1d078
Implement long-press image deletion (without confirmation dialog).
jg210 Jun 5, 2024
38fc459
Try out coil for image loading. Get weird UI glitches in combination …
jg210 Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/detekt.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It's using:
* [ML Kit](https://developers.google.com/ml-kit/vision/face-detection) for face feature detection.
* [Firebase Crashlytics](https://firebase.google.com/docs/crashlytics/) for crash reporting.
* [Firebase Analytics](https://firebase.google.com/docs/analytics).
* [Fresco](https://developers.google.com/ml-kit/) for android Bitmap management.
* [Coil](https://coil-kt.github.io/coil/) for android Bitmap management.
* [Circle CI](https://circleci.com/gh/jg210/merging) for automated build, test and continuous delivery [![CircleCI](https://circleci.com/gh/jg210/merging/tree/develop.svg?style=svg)](https://circleci.com/gh/jg210/merging)
* [Fastlane](https://fastlane.tools/) to publish the app as a beta (early access) release for every commit on the release branch. [<img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' style='height: 2em'/>](https://play.google.com/store/apps/details?id=uk.me.jeremygreen.merging)
* [Material Design](https://material.io/design/).
Expand Down
27 changes: 25 additions & 2 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
* Try out JetPack compose.
- add detekt plugin.
* Try out Jetpack Compose.
- update to material 3 design
x onboarding
x about
X licences
- main
X replace view binding with composables
x top bar
X menu
X make action button start camera app
- save camera image
- show images and faces
- splash
- fresco is quite an old library and doesn't support jetpack compose directly
- coil?
- https://coil-kt.github.io/coil/migrating/#non-view-targets
- glide?
- picasso?
- Is AppTheme etc. required still?
- and AppCompatActivity as parent class
- remove old material library.
- remove viewBinding = true
- replace closeMenu function with Item Composable that also deduplicates DropdownMenuItem boilerplate

* NDK crash reporting

Expand Down Expand Up @@ -84,6 +105,8 @@
* Don't show splashscreen if start up is fast enough
- but if do show it, show it for at least 1.5s.

* Use ActivityResultContract not deprecated startActivityForResult/onActivityResult.

* Enable crashlytics and analytics in SplashActivity if previously enabled via OnboardingActivity.
- currently, enable in MainActivity, which avoids need to persist state, but means
early crashes not visible.
Expand Down
27 changes: 24 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
plugins {
id 'com.android.application'
id 'com.google.android.gms.oss-licenses-plugin'
id 'com.mikepenz.aboutlibraries.plugin'
id 'kotlin-android'
id 'com.google.devtools.ksp'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'io.gitlab.arturbosch.detekt'
}

apply from: '../dependencies.gradle'

static String getBranchName() {
final branchCommand = ["git", "symbolic-ref", "HEAD", "--short"]
return branchCommand.execute().text.trim()
Expand Down Expand Up @@ -57,6 +59,7 @@ android {
buildFeatures {
viewBinding = true
buildConfig = true
compose = true
}
signingConfigs {
release {
Expand All @@ -75,6 +78,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
composeOptions {
kotlinCompilerExtensionVersion = project.ext.kotlinCompilerExtensionVersion
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
Expand All @@ -100,7 +106,18 @@ detekt {
dependencies {
def lifecycle_version = "2.6.2"
def room_version = "2.6.1"
def composeBom = platform('androidx.compose:compose-bom:2024.03.00')
implementation fileTree(dir: 'libs', include: ['*.jar'])

// JetPack Compose
implementation composeBom
implementation 'androidx.compose.material3:material3'
implementation("androidx.compose.runtime:runtime-livedata:1.6.7")
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.activity:activity-compose'
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1"
implementation 'androidx.annotation:annotation:1.7.0'
Expand All @@ -112,23 +129,27 @@ dependencies {
implementation "androidx.room:room-ktx:${room_version}"
implementation "androidx.room:room-runtime:${room_version}"
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation("io.coil-kt:coil:2.6.0")
implementation("io.coil-kt:coil-compose:2.6.0")
implementation 'com.facebook.fresco:fresco:3.1.3'
// https://github.com/facebook/fresco/issues/2598#issuecomment-1110860661
compileOnly 'com.facebook.infer.annotation:infer-annotation:0.18.0'
implementation platform('com.google.firebase:firebase-bom:29.0.4')
implementation 'com.google.firebase:firebase-crashlytics' // versioned with BOM
implementation 'com.google.firebase:firebase-analytics' // versioned with BOM
implementation 'com.google.android.gms:play-services-mlkit-face-detection:16.1.4'
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
implementation 'com.google.android.material:material:1.10.0'
implementation "com.mikepenz:aboutlibraries-compose-m3:${aboutLibsVersion}"
ksp "androidx.room:room-compiler:${room_version}"
testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation "androidx.room:room-testing:${room_version}"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation composeBom
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
detektPlugins("io.gitlab.arturbosch.detekt:detekt-rules-libraries:1.23.6")
detektPlugins("io.gitlab.arturbosch.detekt:detekt-rules-ruleauthors:1.23.6")
detektPlugins 'io.nlopez.compose.rules:detekt:0.3.12'
}

task writeVersionFile {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
android:theme="@style/AppTheme.NoActionBar"
android:exported="false">
</activity>
<activity
android:name=".licences.LicencesActivity"
android:theme="@style/AppTheme.NoActionBar"
android:exported="false">
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
Expand Down
71 changes: 55 additions & 16 deletions app/src/main/java/uk/me/jeremygreen/merging/about/AboutActivity.kt
Original file line number Diff line number Diff line change
@@ -1,38 +1,77 @@
package uk.me.jeremygreen.merging.about

import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import uk.me.jeremygreen.merging.BuildConfig
import uk.me.jeremygreen.merging.R
import uk.me.jeremygreen.merging.databinding.AboutBinding

internal class AboutActivity: AppCompatActivity() {

private val versionName by lazy { packageManager.getPackageInfo(packageName, 0).versionName }

private lateinit var binding: AboutBinding

// Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = AboutBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.aboutToolbar)
binding.appVersion.text = getString(R.string.version, BuildConfig.APPLICATION_ID, versionName)
setContent { About() }
}

// Activity
override fun onResume() {
super.onResume()
binding.aboutToolbar.setNavigationOnClickListener {
finish()
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun About() {
Scaffold(
topBar = {
TopAppBar(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary,
),
title = { Text(text = stringResource(R.string.actionAbout)) },
navigationIcon = { BackButton() }
)
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding),
) {
AboutText()
}
}
}

// Activity
override fun onPause() {
super.onPause()
binding.aboutToolbar.setNavigationOnClickListener(null)
@Composable
private fun AboutText() {
Column(modifier = Modifier.padding(16.dp)) {
Text(stringResource(R.string.version, BuildConfig.APPLICATION_ID, versionName))
}
}

@Composable
private fun BackButton() {
IconButton(onClick = { finish() }) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back",
tint = Color.White
)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package uk.me.jeremygreen.merging.licences

import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import uk.me.jeremygreen.merging.R

internal class LicencesActivity: AppCompatActivity() {

// Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { Licences() }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun Licences() {
Scaffold(
topBar = {
TopAppBar(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary,
),
title = { Text(text = stringResource(R.string.actionLicences)) },
navigationIcon = { BackButton() }
)
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding),
) {
LibrariesContainer(
Modifier.fillMaxSize()
)
}
}
}

@Composable
private fun BackButton() {
IconButton(onClick = { finish() }) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back",
tint = Color.White
)
}
}

}
Loading