Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
RznNike committed Oct 18, 2024
2 parents 3065afe + 95fad7c commit cffe24e
Show file tree
Hide file tree
Showing 269 changed files with 1,746 additions and 1,290 deletions.
44 changes: 23 additions & 21 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.internal.extensions.stdlib.capitalized
import java.util.Properties

plugins {
id("com.android.application")
Expand All @@ -14,13 +14,15 @@ android {
namespace = "ru.rznnike.eyehealthmanager"

compileSdk = rootProject.extra["TARGET_SDK"] as Int
buildToolsVersion = "34.0.0"
buildToolsVersion = "35.0.0"

signingConfigs {
create("config") {
storeFile = file("../eyehealthmanager.jks")
keyAlias = "eyehealthmanager"
val localProperties = gradleLocalProperties(rootDir)
val localProperties = Properties().apply {
rootProject.file("local.properties").reader().use(::load)
}
val keyPass = localProperties.getProperty("PROJECT_KEY_PASSWORD")
val storePass = localProperties.getProperty("PROJECT_KEYSTORE_PASSWORD")
if (keyPass.isNullOrBlank() || storePass.isNullOrBlank()) {
Expand Down Expand Up @@ -106,7 +108,6 @@ android {
viewBinding = true
buildConfig = true
}
@Suppress("UnstableApiUsage")
bundle {
abi.enableSplit = false
language.enableSplit = false
Expand All @@ -120,37 +121,38 @@ android {
}

dependencies {
implementation(project(":data"))
implementation(project(":domain"))
implementation(project(":device"))
implementation(project(":data"))
implementation(project(":resources"))

// Desugaring
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
// https://mvnrepository.com/artifact/com.android.tools/desugar_jdk_libs
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:" + rootProject.extra["desugaringVersion"])

// AndroidX
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
val lifecycleVersion = "2.8.6"
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-process:$lifecycleVersion")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.viewpager2:viewpager2:1.1.0-beta02")
implementation("androidx.annotation:annotation:1.7.1")
implementation("androidx.fragment:fragment-ktx:1.6.2")
implementation("androidx.window:window:1.2.0")
implementation("androidx.viewpager2:viewpager2:1.1.0")
implementation("androidx.annotation:annotation:1.9.0")
implementation("androidx.fragment:fragment-ktx:1.8.4")
implementation("androidx.window:window:1.3.0")

// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:" + rootProject.extra["coroutinesVersion"])
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:" + rootProject.extra["coroutinesVersion"])
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:" + rootProject.extra["coroutinesVersion"])

// Material
implementation("com.google.android.material:material:1.11.0")
implementation("com.google.android.material:material:1.12.0")

// Firebase
implementation("com.google.firebase:firebase-crashlytics-ktx:18.6.1")
implementation("com.google.firebase:firebase-messaging:23.4.0")
implementation("com.google.firebase:firebase-crashlytics-ktx:19.2.0")
implementation("com.google.firebase:firebase-messaging:24.0.2")

// Koin
// https://github.com/InsertKoinIO/koin
Expand Down Expand Up @@ -181,7 +183,7 @@ dependencies {

// Image loader
// https://github.com/coil-kt/coil
implementation("io.coil-kt:coil:2.5.0")
implementation("io.coil-kt:coil:2.7.0")

// MPAndroidChart
// https://github.com/PhilJay/MPAndroidChart
Expand All @@ -204,9 +206,9 @@ dependencies {

// Mocks for testing
// https://github.com/mockito/mockito
val mockitoVersion = "5.9.0"
val mockitoVersion = "5.14.2"
testImplementation("org.mockito:mockito-core:$mockitoVersion")
testImplementation("org.mockito:mockito-junit-jupiter:$mockitoVersion")
// https://github.com/mockito/mockito-kotlin
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
}
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@


<service
android:name=".device.service.NotificationService"
android:name=".app.service.NotificationService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" />

<service
android:name=".device.service.AppFirebaseMessagingService"
android:name=".app.service.AppFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/java/ru/rznnike/eyehealthmanager/app/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ import org.koin.core.logger.Level
import ru.rznnike.eyehealthmanager.BuildConfig
import ru.rznnike.eyehealthmanager.app.di.appComponent
import ru.rznnike.eyehealthmanager.app.observer.AppLifeCycleObserver
import ru.rznnike.eyehealthmanager.data.preference.PreferencesWrapper

class App : Application() {
private val appLifecycleObserver: AppLifeCycleObserver by inject()
private val preferences: PreferencesWrapper by inject()
private val boxStore: BoxStore by inject()

override fun onCreate() {
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/ru/rznnike/eyehealthmanager/app/Screens.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ import ru.rznnike.eyehealthmanager.app.ui.fragment.nearfar.test.NearFarTestFragm
import ru.rznnike.eyehealthmanager.app.ui.fragment.settings.testing.TestingSettingsFragment
import ru.rznnike.eyehealthmanager.app.ui.fragment.splash.SplashFlowFragment
import ru.rznnike.eyehealthmanager.app.ui.fragment.splash.SplashFragment
import ru.rznnike.eyehealthmanager.domain.model.AcuityTestResult
import ru.rznnike.eyehealthmanager.domain.model.AnalysisResult
import ru.rznnike.eyehealthmanager.domain.model.enums.AstigmatismAnswerType
import ru.rznnike.eyehealthmanager.domain.model.enums.DaltonismAnomalyType
import ru.rznnike.eyehealthmanager.domain.model.enums.DayPart
import ru.rznnike.eyehealthmanager.domain.model.enums.NearFarAnswerType
import ru.rznnike.eyehealthmanager.domain.model.test.acuity.AcuityTestResult
import ru.rznnike.eyehealthmanager.domain.model.analysis.AnalysisResult
import ru.rznnike.eyehealthmanager.domain.model.test.astigmatism.AstigmatismAnswerType
import ru.rznnike.eyehealthmanager.domain.model.test.daltonism.DaltonismAnomalyType
import ru.rznnike.eyehealthmanager.domain.model.common.DayPart
import ru.rznnike.eyehealthmanager.domain.model.test.nearfar.NearFarAnswerType

object Screens {
object Flow {
Expand Down
25 changes: 14 additions & 11 deletions app/src/main/java/ru/rznnike/eyehealthmanager/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package ru.rznnike.eyehealthmanager.app.di
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.module
import ru.rznnike.eyehealthmanager.app.crash.CrashlyticsProvider
import ru.rznnike.eyehealthmanager.app.crash.CrashlyticsProviderImpl
Expand All @@ -12,29 +12,32 @@ import ru.rznnike.eyehealthmanager.app.dispatcher.external.ExternalIntentDispatc
import ru.rznnike.eyehealthmanager.app.dispatcher.notifier.Notifier
import ru.rznnike.eyehealthmanager.app.global.presentation.ErrorHandler
import ru.rznnike.eyehealthmanager.app.observer.AppLifeCycleObserver
import ru.rznnike.eyehealthmanager.device.notification.Notificator
import ru.rznnike.eyehealthmanager.domain.global.CoroutineProvider
import ru.rznnike.eyehealthmanager.app.notification.Notificator
import ru.rznnike.eyehealthmanager.app.utils.JournalBackupManagerAndroid
import ru.rznnike.eyehealthmanager.app.utils.JournalBackupManagerAndroidImpl
import ru.rznnike.eyehealthmanager.domain.global.CoroutineScopeProvider
import ru.rznnike.eyehealthmanager.domain.global.DispatcherProvider
import java.time.Clock

val appModule = module {
factory { androidContext().resources }
factory { androidApplication().resources }

factory { AppLifeCycleObserver() }
single { Notifier(get()) }
single { ErrorHandler(get(), get()) }
single { EventDispatcher(get()) }
single { ExternalIntentDispatcher(get()) }
single { Notificator(androidContext()) }
single { Notificator() }
single<CrashlyticsProvider> { CrashlyticsProviderImpl() }
single { Clock.systemUTC() }
factory<JournalBackupManagerAndroid> { JournalBackupManagerAndroidImpl() }

single<CoroutineProvider> {
object : CoroutineProvider {
override val scopeIo = CoroutineScope(Dispatchers.IO)
override val scopeMain = MainScope()
override val scopeMainImmediate = CoroutineScope(Dispatchers.Main.immediate)
override val scopeUnconfined = CoroutineScope(Dispatchers.Unconfined)
single<CoroutineScopeProvider> {
object : CoroutineScopeProvider {
override val ui = MainScope()
override val default = CoroutineScope(Dispatchers.Default)
override val io = CoroutineScope(Dispatchers.IO)
override val unconfined = CoroutineScope(Dispatchers.Unconfined)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import ru.rznnike.eyehealthmanager.domain.gateway.TestGateway
import ru.rznnike.eyehealthmanager.domain.gateway.UserGateway

val gatewayModule = module {
single<UserGateway> { UserGatewayImpl(get()) }
single<NotificationGateway> { NotificationGatewayImpl() }
single<UserGateway> { UserGatewayImpl(get(), get()) }
single<NotificationGateway> { NotificationGatewayImpl(get()) }
single<TestGateway> { TestGatewayImpl(get(), get(), get()) }
single<AnalysisGateway> { AnalysisGatewayImpl(get(), get()) }
single<DevGateway> { DevGatewayImpl(get(), get()) }
single<AnalysisGateway> { AnalysisGatewayImpl(get(), get(), get()) }
single<DevGateway> { DevGatewayImpl(get(), get(), get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ val interactorModule = module {
single { DeleteAllTestResultsUseCase(get(), get()) }
single { DeleteDuplicatesUseCase(get(), get()) }
single { ExportJournalUseCase(get(), get()) }
single { GetAvailableImportTypesUseCase(get(), get()) }
single { ImportJournalUseCase(get(), get()) }

single { GetAnalysisResultUseCase(get(), get()) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package ru.rznnike.eyehealthmanager.app.dispatcher.event

import kotlinx.coroutines.launch
import ru.rznnike.eyehealthmanager.domain.global.CoroutineProvider
import ru.rznnike.eyehealthmanager.domain.global.CoroutineScopeProvider
import java.util.*
import kotlin.reflect.KClass

class EventDispatcher(
private val coroutineProvider: CoroutineProvider
private val coroutineScopeProvider: CoroutineScopeProvider
) {
private val eventListeners = HashMap<String, MutableList<EventListener>>()

Expand Down Expand Up @@ -36,16 +36,16 @@ class EventDispatcher(
}

fun removeEventListener(listener: EventListener) = eventListeners
.filter { it.value.size > 0 }
.filter { it.value.isNotEmpty() }
.forEach { it.value.remove(listener) }

fun sendEvent(appEvent: AppEvent) {
val key = appEvent::class.java.name
eventListeners
.filter { it.key == key && it.value.size > 0 }
.filter { it.key == key && it.value.isNotEmpty() }
.forEach {
it.value.forEach { listener ->
coroutineProvider.scopeMain.launch {
coroutineScopeProvider.ui.launch {
listener.onEvent(appEvent)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package ru.rznnike.eyehealthmanager.app.dispatcher.external
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import ru.rznnike.eyehealthmanager.domain.global.CoroutineProvider
import ru.rznnike.eyehealthmanager.domain.model.ExternalIntentData
import ru.rznnike.eyehealthmanager.domain.global.CoroutineScopeProvider
import ru.rznnike.eyehealthmanager.domain.model.common.ExternalIntentData

class ExternalIntentDispatcher(
private val coroutineProvider: CoroutineProvider
private val coroutineScopeProvider: CoroutineScopeProvider
) {
private val eventsFlow = MutableStateFlow<ExternalIntentData>(
ExternalIntentData.App().apply { processed = true }
Expand All @@ -16,7 +16,7 @@ class ExternalIntentDispatcher(
fun subscribe() = eventsFlow.asStateFlow()

fun send(data: ExternalIntentData) {
coroutineProvider.scopeIo.launch {
coroutineScopeProvider.io.launch {
eventsFlow.emit(data)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import androidx.annotation.StringRes
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import ru.rznnike.eyehealthmanager.domain.global.CoroutineProvider
import ru.rznnike.eyehealthmanager.domain.global.CoroutineScopeProvider

class Notifier(
private val coroutineProvider: CoroutineProvider
private val coroutineScopeProvider: CoroutineScopeProvider
) {
private val notifierFlow = MutableSharedFlow<SystemMessage>()

Expand Down Expand Up @@ -86,7 +86,7 @@ class Notifier(
)

private fun emitMessage(message: SystemMessage) {
coroutineProvider.scopeIo.launch {
coroutineScopeProvider.io.launch {
notifierFlow.emit(message)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ru.rznnike.eyehealthmanager.app.global.presentation.ErrorHandler
import ru.rznnike.eyehealthmanager.app.global.ui.fragment.BaseFragment
import ru.rznnike.eyehealthmanager.app.utils.extensions.applyTheme
import ru.rznnike.eyehealthmanager.data.preference.PreferencesWrapper
import ru.rznnike.eyehealthmanager.domain.model.enums.AppTheme
import ru.rznnike.eyehealthmanager.domain.model.common.AppTheme

abstract class BaseActivity(@LayoutRes layoutRes: Int) : MvpAppCompatActivity(layoutRes) {
private val preferences: PreferencesWrapper by inject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import kotlin.concurrent.schedule

abstract class BaseFragment(@LayoutRes layoutRes: Int) : MvpAppCompatFragment(layoutRes) {
open var isLightStatusBar: Boolean = true
get() = !(context?.isNightModeEnabled ?: false)
get() = context?.isNightModeEnabled != true
protected set
open var isLightNavigationBar: Boolean = true
get() = !(context?.isNightModeEnabled ?: false)
get() = context?.isNightModeEnabled != true
protected set
open var progressDelayMs: Long = DEFAULT_PROGRESS_DELAY_MS
protected set
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.rznnike.eyehealthmanager.app.model.common

import androidx.annotation.StringRes
import ru.rznnike.eyehealthmanager.R
import ru.rznnike.eyehealthmanager.domain.model.common.AppTheme

enum class AppThemeVM(
val data: AppTheme,
@StringRes val nameResId: Int
) {
LIGHT(
data = AppTheme.LIGHT,
nameResId = R.string.theme_light
),
DARK(
data = AppTheme.DARK,
nameResId = R.string.theme_dark
),
SYSTEM(
data = AppTheme.SYSTEM,
nameResId = R.string.theme_system
);

companion object {
operator fun get(data: AppTheme?) = entries.find { it.data == data } ?: SYSTEM
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.rznnike.eyehealthmanager.app.model.notification

import androidx.annotation.StringRes
import ru.rznnike.eyehealthmanager.R
import ru.rznnike.eyehealthmanager.domain.model.notification.NotificationChannelType

enum class NotificationChannelTypeVM(
val data: NotificationChannelType,
@StringRes val nameResId: Int
) {
SYSTEM(
data = NotificationChannelType.SYSTEM,
nameResId = R.string.notification_channel_system
);

companion object {
operator fun get(data: NotificationChannelType?) = entries.find { it.data == data } ?: SYSTEM
}
}
Loading

0 comments on commit cffe24e

Please sign in to comment.