Skip to content

Commit

Permalink
Merge pull request #521 from igorescodro/amm/domain
Browse files Browse the repository at this point in the history
Convert the Domain module to a KMP module
  • Loading branch information
igorescodro authored Aug 3, 2023
2 parents a892a62 + 9a9034b commit 2c8cffc
Show file tree
Hide file tree
Showing 132 changed files with 904 additions and 779 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/android_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Run instrumented tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 24
api-level: 27
profile: Galaxy Nexus
disable-animations: true
disk-size: 2000M
Expand Down
20 changes: 11 additions & 9 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ plugins {
android {
defaultConfig {
applicationId = "com.escodro.alkaa"
versionCode = AlkaaVersions.versionCode
versionName = AlkaaVersions.versionName
versionCode = Integer.parseInt(libs.versions.version.code.get())
versionName = libs.versions.version.name.get()

compileSdk = AlkaaVersions.compileSdk
minSdk = AlkaaVersions.minSdk
targetSdk = AlkaaVersions.targetSdk
compileSdk = Integer.parseInt(libs.versions.android.sdk.compile.get())
minSdk = Integer.parseInt(libs.versions.android.sdk.min.get())
targetSdk = Integer.parseInt(libs.versions.android.sdk.target.get())
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

setProperty("archivesBaseName", "${parent?.name}-$versionName")
Expand Down Expand Up @@ -55,8 +55,8 @@ android {
setDynamicFeatures(setOf(":features:tracker"))

compileOptions {
sourceCompatibility = AlkaaVersions.javaCompileVersion
targetCompatibility = AlkaaVersions.javaCompileVersion
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

buildFeatures {
Expand All @@ -67,7 +67,7 @@ android {
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}

packagingOptions {
packaging {
resources.excludes.apply {
add("META-INF/AL2.0")
add("META-INF/LGPL2.1")
Expand Down Expand Up @@ -107,14 +107,15 @@ dependencies {
implementation(projects.data.local)
implementation(projects.data.datastore)
implementation(projects.data.repository)
implementation(projects.domain)
implementation(projects.features.task)
implementation(projects.features.alarm)
implementation(projects.features.category)
implementation(projects.features.preference)
implementation(projects.features.search)
implementation(projects.features.glance)

implementation(projects.domain)

implementation(platform(libs.compose.bom))

implementation(libs.logcat)
Expand All @@ -129,6 +130,7 @@ dependencies {

implementation(libs.bundles.compose)
implementation(libs.kotlinx.collections.immutable)
implementation(libs.kotlinx.datetime)

androidTestUtil(libs.test.orchestrator)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import com.escodro.alkaa.navigation.NavGraph
import com.escodro.alkaa.util.WindowSizeClassFake
import com.escodro.core.extension.getNotificationManager
import com.escodro.core.extension.toLocalDateTime
import com.escodro.domain.usecase.alarm.ScheduleAlarm
import com.escodro.local.model.AlarmInterval
import com.escodro.local.model.Task
Expand Down Expand Up @@ -227,7 +228,7 @@ internal class NotificationFlowTest : KoinTest {
calendar.add(Calendar.SECOND, 1)
dueDate = calendar
daoProvider.getTaskDao().insertTask(this)
scheduleAlarm(this.id, this.dueDate!!)
scheduleAlarm(this.id, this.dueDate!!.toLocalDateTime())
this
}

Expand All @@ -239,7 +240,7 @@ internal class NotificationFlowTest : KoinTest {
isRepeating = true
alarmInterval = AlarmInterval.HOURLY
daoProvider.getTaskDao().insertTask(this)
scheduleAlarm(this.id, this.dueDate!!)
scheduleAlarm(this.id, this.dueDate!!.toLocalDateTime())
}
}
}
9 changes: 7 additions & 2 deletions data/repository/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
plugins {
id("com.escodro.kotlin-module")
id("com.android.lint")
id("com.escodro.android-library") // TODO revert to Kotlin-only
}

dependencies {
implementation(projects.domain)
implementation(projects.libraries.core)

implementation(libs.koin.core)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.datetime)
}

android {
namespace = "com.escodro.repository"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.escodro.repository.mapper

import com.escodro.core.extension.toCalendar
import com.escodro.core.extension.toLocalDateTime
import com.escodro.domain.model.Task as DomainTask
import com.escodro.repository.model.Task as RepoTask

Expand All @@ -22,9 +24,9 @@ internal class TaskMapper(private val alarmIntervalMapper: AlarmIntervalMapper)
title = repoTask.title,
description = repoTask.description,
categoryId = repoTask.categoryId,
dueDate = repoTask.dueDate,
creationDate = repoTask.creationDate,
completedDate = repoTask.completedDate,
dueDate = repoTask.dueDate?.toLocalDateTime(),
creationDate = repoTask.creationDate?.toLocalDateTime(),
completedDate = repoTask.completedDate?.toLocalDateTime(),
isRepeating = repoTask.isRepeating,
alarmInterval = repoTask.alarmInterval?.let { alarmIntervalMapper.toDomain(it) },
)
Expand Down Expand Up @@ -53,9 +55,9 @@ internal class TaskMapper(private val alarmIntervalMapper: AlarmIntervalMapper)
title = domainTask.title,
description = domainTask.description,
categoryId = domainTask.categoryId,
dueDate = domainTask.dueDate,
creationDate = domainTask.creationDate,
completedDate = domainTask.completedDate,
dueDate = domainTask.dueDate?.toCalendar(),
creationDate = domainTask.creationDate?.toCalendar(),
completedDate = domainTask.completedDate?.toCalendar(),
isRepeating = domainTask.isRepeating,
alarmInterval = domainTask.alarmInterval?.let { alarmIntervalMapper.toRepo(it) },
)
Expand Down
1 change: 0 additions & 1 deletion domain/.gitignore

This file was deleted.

3 changes: 0 additions & 3 deletions domain/README.md

This file was deleted.

59 changes: 49 additions & 10 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
plugins {
id("com.escodro.kotlin-module")
id("com.android.lint")
kotlin("multiplatform")
id("com.android.library")
id("com.escodro.kotlin-quality")
}

dependencies {
implementation(libs.koin.core)
implementation(libs.logging)
runtimeOnly(libs.logback)
implementation(libs.kotlinx.coroutines.core)
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
targetHierarchy.default()

testImplementation(libs.test.junit)
testImplementation(libs.test.mockk)
testImplementation(libs.kotlinx.coroutines.test)
android {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "domain"
}
}

sourceSets {
val commonMain by getting {
dependencies {
implementation(libs.koin.core)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.logging)
implementation(libs.logback)
implementation(libs.kotlinx.datetime)
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(libs.kotlinx.coroutines.test)
}
}
}
}

android {
namespace = "com.escodro.domain"
compileSdk = Integer.parseInt(libs.versions.android.sdk.compile.get())
defaultConfig {
minSdk = Integer.parseInt(libs.versions.android.sdk.min.get())
}
}
26 changes: 0 additions & 26 deletions domain/proguard-rules.pro

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.escodro.domain.di

import com.escodro.domain.provider.CalendarProvider
import com.escodro.domain.provider.CalendarProviderImpl
import com.escodro.domain.provider.DateTimeProvider
import com.escodro.domain.provider.DateTimeProviderImpl
import com.escodro.domain.usecase.alarm.CancelAlarm
import com.escodro.domain.usecase.alarm.RescheduleFutureAlarms
import com.escodro.domain.usecase.alarm.ScheduleAlarm
Expand Down Expand Up @@ -100,5 +100,5 @@ val domainModule = module {
factoryOf(::LoadAppTheme)

// Providers
factoryOf(::CalendarProviderImpl) bind CalendarProvider::class
factoryOf(::DateTimeProviderImpl) bind DateTimeProvider::class
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.escodro.domain.model

import java.util.Calendar
import kotlinx.datetime.LocalDateTime

/**
* Data class to represent a Task.
Expand All @@ -22,9 +22,9 @@ data class Task(
val title: String,
val description: String? = null,
val categoryId: Long? = null,
val dueDate: Calendar? = null,
val creationDate: Calendar? = null,
val completedDate: Calendar? = null,
val dueDate: LocalDateTime? = null,
val creationDate: LocalDateTime? = null,
val completedDate: LocalDateTime? = null,
val isRepeating: Boolean = false,
val alarmInterval: AlarmInterval? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.escodro.domain.provider

import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime

/**
* Provide the date and time to be used on the task use cases, respecting the Inversion of Control.
*/
interface DateTimeProvider {

/**
* Gets the current [Instant].
*
* @return the current [Instant]
*/
fun getCurrentInstant(): Instant

fun getCurrentLocalDateTime(): LocalDateTime
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.escodro.domain.provider

import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

internal class DateTimeProviderImpl : DateTimeProvider {

override fun getCurrentInstant(): Instant = Clock.System.now()

override fun getCurrentLocalDateTime(): LocalDateTime = getCurrentInstant()
.toLocalDateTime(TimeZone.currentSystemDefault())
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@ package com.escodro.domain.usecase.alarm

import com.escodro.domain.interactor.AlarmInteractor
import com.escodro.domain.model.Task
import com.escodro.domain.provider.CalendarProvider
import com.escodro.domain.provider.DateTimeProvider
import com.escodro.domain.repository.TaskRepository
import mu.KLogging
import java.util.Calendar
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import mu.KotlinLogging

/**
* Use case to reschedule tasks scheduled in the future or missing repeating.
*/
class RescheduleFutureAlarms(
private val taskRepository: TaskRepository,
private val alarmInteractor: AlarmInteractor,
private val calendarProvider: CalendarProvider,
private val dateTimeProvider: DateTimeProvider,
private val scheduleNextAlarm: ScheduleNextAlarm,
) {

private val logger = KotlinLogging.logger {}

/**
* Reschedule scheduled and misses repeating tasks.
*/
Expand All @@ -29,18 +34,21 @@ class RescheduleFutureAlarms(
missedRepeating.forEach { rescheduleRepeatingTask(it) }
}

private fun isInFuture(calendar: Calendar?): Boolean {
val currentTime = calendarProvider.getCurrentCalendar()
return calendar?.after(currentTime) ?: false
private fun isInFuture(localDateTime: LocalDateTime?): Boolean {
val currentTime = dateTimeProvider.getCurrentInstant()
val givenTime = localDateTime?.toInstant(TimeZone.currentSystemDefault()) ?: return false
return givenTime > currentTime
}

private fun isMissedRepeating(task: Task): Boolean {
val currentTime = calendarProvider.getCurrentCalendar()
return task.isRepeating && task.dueDate?.before(currentTime) ?: false
val currentTime = Clock.System.now()
val givenTime = task.dueDate?.toInstant(TimeZone.currentSystemDefault()) ?: return false
return task.isRepeating && currentTime > givenTime
}

private fun rescheduleFutureTask(task: Task) {
val futureTime = task.dueDate?.time?.time ?: return
val futureTime = task.dueDate
?.toInstant(TimeZone.currentSystemDefault())?.toEpochMilliseconds() ?: return
alarmInteractor.schedule(task.id, futureTime)
logger.debug { "Task '${task.title} rescheduled to '${task.dueDate}" }
}
Expand All @@ -49,6 +57,4 @@ class RescheduleFutureAlarms(
scheduleNextAlarm(task)
logger.debug { "Repeating task '${task.title} rescheduled to '${task.dueDate}" }
}

companion object : KLogging()
}
Loading

0 comments on commit 2c8cffc

Please sign in to comment.