Skip to content

Commit

Permalink
Repetitive tasks and other enhancements (#129)
Browse files Browse the repository at this point in the history
* Refactor get task by id usecase

* Add index for date to fetch tasks faster

* Upgrade libraries and AGP

* Re-arrange files of :core and :core:ui modules

* Improve ClearableChip functionality to clear only when tapping on the X

In the previous design, selecting the chip and tapping anywhere on it
would clear the content, which could lead to unintentional clearing

* Record screenshot tests

* Add recurrence UI

Also improve create task layout reducing paddings and the UI overall

* Upgrade compose destinations to latest version

* Add recurrence when creating a task

* Create next occurrence when mark recurrent task as done

* Add remove logic for recurring tasks

As Google Calendar does, the user will be able to choose between
removing only a single recurring tasks, the chosen one plus its
following occurrences and the last one all the recurring tasks related

* Add fake tasks

* Add recurrence info to the TaskCard

* Fix remove recurring task by the parent one

* Create next occurrences for recurring tasks

* Improve files structure adding UI package

* Remove balloon library

* Upgrade some libs

* Make expanded header calendar scrollable and improve agenda structure

* Remove compose activity dependency from feature plugin

* Make month and week calendar scrollable for better navigation

* Rename interactor folder to usecase

* Increase minimum Android version to API 26 (Android 8)

* Record screenshot tests

* Remove tests that were checking recurrence when mark tasks as done

* Add daily job to populate recurring tasks when needed

* Rename UpdateTaskUseCase.kt to EditTaskUseCase.kt

* Fix week calendar scrolling to selected day when day is updated

* Remove unused mapper

* Fix flaky tests

* Fix edit recurring tasks

* Add progress indicator when saving on the create task expanded screen

* Handle and test Room migrations

* Disable TooGenericExceptionCaught rule

* Fix lint errors

* Fix package id for different build variants

Specifically, baseline profile tests were fixed

* Upgrade Gradle to 8.5

* Upgrade AGP to 8.2.1

* Upgrade MockK and fix tests

* Remove horizontal calendar screenshot test
  • Loading branch information
costular authored Jan 16, 2024
1 parent 5704926 commit 45a9ecc
Show file tree
Hide file tree
Showing 290 changed files with 4,991 additions and 1,350 deletions.
11 changes: 10 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ android {
buildTypes {
release {
signingConfig = signingConfigs.getByName("production")
baselineProfile.automaticGenerationDuringBuild = true
}
}
}
Expand Down Expand Up @@ -90,6 +91,7 @@ dependencies {
implementation(projects.feature.postponeTask)

implementation(libs.fragment)
implementation(libs.compose.activity)
implementation(libs.compose.ui)
implementation(libs.compose.material3)
implementation(libs.compose.material3.windowsize)
Expand All @@ -102,7 +104,6 @@ dependencies {
implementation(libs.viewmodel)
implementation(libs.hilt)
implementation(libs.profileinstaller)
"baselineProfile"(project(":baselineprofile"))
kapt(libs.hilt.compiler)
implementation(libs.hilt.work)
implementation(libs.hilt.navigation.compose)
Expand All @@ -125,6 +126,14 @@ dependencies {
testImplementation(libs.compose.ui.test)

androidTestImplementation(projects.core.testing)

baselineProfile(projects.benchmarks)
}

baselineProfile {
// Don't build on every iteration of a full assemble.
// Instead enable generation directly for the release build variant.
automaticGenerationDuringBuild = false
}

class RoomSchemaArgProvider(
Expand Down
3 changes: 2 additions & 1 deletion app/config/detekt/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ exceptions:
ThrowingNewInstanceOfSameException:
active: true
TooGenericExceptionCaught:
active: true
active: false
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
exceptionNames:
- 'ArrayIndexOutOfBoundsException'
Expand Down Expand Up @@ -625,6 +625,7 @@ style:
ignoreEnums: false
ignoreRanges: false
ignoreExtensionFunctions: true
ignoreAnnotated: ['Preview']
MandatoryBracesLoops:
active: false
MaxChainedCallsOnSameLine:
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/java/com/costular/atomtasks/data/BootReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.work.WorkManager
import com.costular.atomtasks.tasks.manager.TaskReminderManager
import com.costular.atomtasks.tasks.helper.recurrence.RecurrenceScheduler
import com.costular.atomtasks.tasks.worker.SetTasksRemindersWorker
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
Expand All @@ -13,11 +13,12 @@ import javax.inject.Inject
class BootReceiver : BroadcastReceiver() {

@Inject
lateinit var taskReminderManager: TaskReminderManager
lateinit var recurrenceScheduler: RecurrenceScheduler

override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
WorkManager.getInstance(context).enqueue(SetTasksRemindersWorker.start())
recurrenceScheduler.initialize()
}
}
}
6 changes: 3 additions & 3 deletions app/src/main/java/com/costular/atomtasks/ui/AtomTasksApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.costular.atomtasks.BuildConfig
import com.costular.atomtasks.core.logging.AtomLogger
import com.costular.atomtasks.core.logging.FirebaseAtomLogger
import com.costular.atomtasks.core.logging.LogcatAtomLogger
import com.costular.atomtasks.tasks.manager.AutoforwardManager
import com.costular.atomtasks.tasks.helper.AutoforwardManager
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.HiltAndroidApp
Expand Down Expand Up @@ -42,8 +42,8 @@ class AtomTasksApp : Application(), Configuration.Provider {
AtomLogger.initialize(logger)
}

override fun getWorkManagerConfiguration() =
Configuration.Builder()
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(Log.DEBUG)
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.costular.atomtasks.ui.home

import androidx.navigation.NavController
import com.costular.atomtasks.agenda.AgendaNavigator
import com.costular.atomtasks.agenda.ui.AgendaNavigator
import com.costular.atomtasks.agenda.destinations.TasksActionsBottomSheetDestination
import com.costular.atomtasks.createtask.destinations.CreateTaskScreenDestination
import com.costular.atomtasks.settings.SettingsNavigator
Expand Down
57 changes: 0 additions & 57 deletions baselineprofile/build.gradle.kts

This file was deleted.

File renamed without changes.
69 changes: 69 additions & 0 deletions benchmarks/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import com.android.build.api.dsl.ManagedVirtualDevice
import com.costular.atomtasks.AtomBuildType
import com.costular.atomtasks.configureFlavors

plugins {
id("atomtasks.android.test")
id("androidx.baselineprofile")
}

android {
namespace = "com.costular.atomtasks.baselineprofile"

defaultConfig {
minSdk = 28
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "APP_BUILD_TYPE_SUFFIX", "\"\"")
}

buildFeatures {
buildConfig = true
}

buildTypes {
// This benchmark buildType is used for benchmarking, and should function like your
// release build (for example, with minification on). It's signed with a debug key
// for easy local/CI testing.
create("benchmark") {
// Keep the build type debuggable so we can attach a debugger if needed.
isDebuggable = true
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
buildConfigField(
"String",
"APP_BUILD_TYPE_SUFFIX",
"\"${AtomBuildType.BENCHMARK.applicationIdSuffix ?: ""}\""
)
}
}

configureFlavors(this) { flavor ->
buildConfigField(
"String",
"APP_FLAVOR_SUFFIX",
"\"${flavor.applicationIdSuffix ?: ""}\""
)
}

testOptions.managedDevices.devices {
create<ManagedVirtualDevice>("pixel6Api34") {
device = "Pixel 6"
apiLevel = 34
systemImageSource = "google"
}
}
targetProjectPath = ":app"
}

baselineProfile {
managedDevices += "pixel6Api34"
useConnectedDevices = false
}

dependencies {
implementation(libs.androidx.test.ext.junit)
implementation(libs.espresso.core)
implementation(libs.uiautomator)
implementation(libs.benchmark.macro.junit4)
}
File renamed without changes.
4 changes: 4 additions & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,9 @@ gradlePlugin {
id = "atomtasks.android.hilt"
implementationClass = "AndroidHiltConventionPlugin"
}
register("androidTest") {
id = "atomtasks.android.test"
implementationClass = "AndroidTestConventionPlugin"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class AndroidFeatureConventionPlugin : Plugin<Project> {
dependencies {
add("implementation", project(":core:designsystem"))
add("implementation", project(":data"))
add("implementation", libs.findLibrary("compose.activity").get())
add("implementation", libs.findLibrary("compose.foundation").get())
add("implementation", libs.findLibrary("compose.runtime").get())
add("implementation", libs.findLibrary("compose.layout").get())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import com.android.build.gradle.TestExtension
import com.costular.atomtasks.configureKotlinAndroid
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure

class AndroidTestConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.test")
apply("org.jetbrains.kotlin.android")
}

extensions.configure<TestExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.costular.atomtasks
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.ApplicationProductFlavor
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.ProductFlavor
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension

enum class FlavorDimension(
Expand All @@ -11,22 +12,32 @@ enum class FlavorDimension(
Environment("environment")
}

enum class Flavor(
enum class AtomFlavor(
val naming: String,
val dimension: FlavorDimension,
val applicationIdSuffix: String? = null,
) {
Development("development", FlavorDimension.Environment, applicationIdSuffix = ".dev"),
Production("production", FlavorDimension.Environment)
Production("production", FlavorDimension.Environment),
}

fun configureFlavors(commonExtensions: CommonExtension<*, *, *, *, *>) {
enum class AtomBuildType(val applicationIdSuffix: String? = null) {
DEBUG,
RELEASE,
BENCHMARK(".benchmark")
}

fun configureFlavors(
commonExtensions: CommonExtension<*, *, *, *, *>,
flavorConfigurationBlock: ProductFlavor.(atomFlavor: AtomFlavor) -> Unit = {},
) {
commonExtensions.apply {
flavorDimensions += FlavorDimension.Environment.naming
productFlavors {
Flavor.values().forEach { flavor ->
AtomFlavor.values().forEach { flavor ->
create(flavor.naming) {
dimension = flavor.dimension.naming
flavorConfigurationBlock(this, flavor)
if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) {
flavor.applicationIdSuffix?.let {
applicationIdSuffix = it
Expand All @@ -39,19 +50,28 @@ fun configureFlavors(commonExtensions: CommonExtension<*, *, *, *, *>) {
}

fun configureBuildTypes(baseAppModuleExtension: BaseAppModuleExtension) {
with (baseAppModuleExtension) {
with(baseAppModuleExtension) {
buildTypes {
getByName("release") {
val release = getByName("release") {
isDebuggable = false
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
applicationIdSuffix = AtomBuildType.RELEASE.applicationIdSuffix
}
getByName("debug") {
isDebuggable = true
isMinifyEnabled = false
isShrinkResources = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
applicationIdSuffix = AtomBuildType.DEBUG.applicationIdSuffix
}
create("benchmark") {
initWith(release)
matchingFallbacks.add("release")
proguardFiles("benchmark-rules.pro")
isMinifyEnabled = true
applicationIdSuffix = AtomBuildType.BENCHMARK.applicationIdSuffix
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal fun Project.configureKotlinAndroid(
compileSdk = 34

defaultConfig {
minSdk = 23
minSdk = 26
}

compileOptions {
Expand Down
2 changes: 1 addition & 1 deletion build-logic/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Sat Jul 22 01:09:57 WEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
1 change: 1 addition & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ dependencyResolutionManagement {
}
}

rootProject.name = "build-logic"
include(":convention")
3 changes: 1 addition & 2 deletions common/tasks/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ android {
dependencies {
implementation(projects.core.designsystem)
implementation(projects.core.analytics)
implementation(projects.core.ui)
implementation(projects.data)
implementation(projects.core.notifications)
implementation(projects.core.logging)

implementation(libs.compose.activity)
implementation(libs.compose.foundation)
implementation(libs.compose.runtime)
implementation(libs.compose.layout)
Expand All @@ -43,7 +43,6 @@ dependencies {
implementation(libs.accompanist.permissions)
kapt(libs.hilt.ext.compiler)
api(libs.reordeable)
implementation(libs.balloon)

testImplementation(projects.common.tasks)
testImplementation(projects.core.testing)
Expand Down
Loading

0 comments on commit 45a9ecc

Please sign in to comment.