Skip to content

Commit

Permalink
Merge pull request #6 from makeevrserg/develop
Browse files Browse the repository at this point in the history
wear integration
  • Loading branch information
makeevrserg authored Oct 11, 2023
2 parents 7b7c1e2 + 33740b1 commit 6d6d87b
Show file tree
Hide file tree
Showing 102 changed files with 2,446 additions and 406 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ androidApp/private_key.pepk
androidApp/google-services.json
androidApp/keystore.jks
desktop/build
wearApp/build
keys.properties
# iosApp
iosApp/Pods
Expand All @@ -38,6 +39,7 @@ modules/services/file_system/build
modules/services/xlsx/build
modules/services/xlsx/libs
modules/services/ads-yandex/build
modules/services/wear-messenger/build
# Features ----------------------------------
modules/features/dialog-confirm/build
modules/features/words-local/build
Expand Down
32 changes: 23 additions & 9 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ android {
applicationId = projectInfo.group
versionCode = gradleProperty("project.version.code").integer
versionName = projectInfo.versionString
setProperty("archivesBaseName", "${projectInfo.name}-${projectInfo.versionString}")
}
defaultConfig {
multiDexEnabled = true
Expand All @@ -32,9 +33,15 @@ android {
}

signingConfigs {
val secretKeyAlias = runCatching { secretProperty("KEY_ALIAS").string }.getOrNull() ?: ""
val secretKeyPassword = runCatching { secretProperty("KEY_PASSWORD").string }.getOrNull() ?: ""
val secretStorePassword = runCatching { secretProperty("STORE_PASSWORD").string }.getOrNull() ?: ""
val secretKeyAlias = runCatching {
secretProperty("KEY_ALIAS").string
}.getOrNull() ?: ""
val secretKeyPassword = runCatching {
secretProperty("KEY_PASSWORD").string
}.getOrNull() ?: ""
val secretStorePassword = runCatching {
secretProperty("STORE_PASSWORD").string
}.getOrNull() ?: ""
getByName("debug") {
if (file("keystore.jks").exists()) {
keyAlias = secretKeyAlias
Expand Down Expand Up @@ -79,16 +86,14 @@ android {
add("META-INF/LGPL2.1")
}
}
buildTypes {
// applicationVariants.all(
// com.makeevrserg.empireprojekt.mobile.ApplicationVariantAction(
// project
// )
// )
lint {
abortOnError = false
}
}

dependencies {
// Kotlin
implementation(libs.kotlin.serialization.json)
// Coroutines
implementation(libs.kotlin.coroutines.core)
implementation(libs.kotlin.coroutines.android)
Expand All @@ -114,13 +119,22 @@ dependencies {
implementation(libs.klibs.mikro.platform)
implementation(libs.klibs.kstorage)
implementation(libs.klibs.kdi)
// moko
implementation(libs.moko.resources.core)
// Decompose
implementation(libs.decompose.core)
implementation(libs.decompose.compose.jetpack)
implementation(libs.decompose.android)
implementation("com.google.android.gms:play-services-wearable:18.0.0")
// wear
implementation("com.google.android.horologist:horologist-datalayer:0.5.3")
// work
implementation("androidx.work:work-runtime:2.8.0")
implementation("androidx.work:work-runtime-ktx:2.8.0")
// Local
implementation(projects.modules.features.root)
implementation(projects.modules.features.ui)
implementation(projects.modules.services.coreUi)
implementation(projects.modules.services.resources)
implementation(projects.modules.services.wearMessenger)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,37 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.runtime.getValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
import com.arkivanov.decompose.defaultComponentContext
import com.makeevrserg.empireprojekt.mobile.application.App.Companion.asEmpireApp
import com.makeevrserg.empireprojekt.mobile.core.ui.rememberSlotModalBottomSheetState
import com.makeevrserg.empireprojekt.mobile.core.ui.theme.AppTheme
import com.makeevrserg.empireprojekt.mobile.features.root.DefaultRootBottomSheetComponent
import com.makeevrserg.empireprojekt.mobile.features.root.DefaultRootComponent
import com.makeevrserg.empireprojekt.mobile.features.root.di.RootModule
import com.makeevrserg.empireprojekt.mobile.features.root.modal.DefaultRootBottomSheetComponent
import com.makeevrserg.empireprojekt.mobile.features.ui.info.InfoScreen
import com.makeevrserg.empireprojekt.mobile.features.ui.root.ApplicationContent
import com.makeevrserg.empireprojekt.mobile.features.ui.root.ComposeApplication
import com.makeevrserg.empireprojekt.mobile.resources.R
import ru.astrainteractive.klibs.kdi.Provider
import ru.astrainteractive.klibs.kdi.getValue

@ExperimentalMaterialApi
@ExperimentalComposeUiApi
@ExperimentalAnimationApi
@ExperimentalFoundationApi
class MainActivity : ComponentActivity() {
private val rootModule by RootModule
private val servicesModule by rootModule.servicesModule
private val rootModule by Provider {
application.asEmpireApp().rootModule
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setTheme(R.style.AppTheme)
val componentContext = defaultComponentContext()
val rootComponent = DefaultRootComponent(componentContext, rootModule, servicesModule)
val rootComponent = DefaultRootComponent(componentContext, rootModule)
val rootBottomSheetComponent = rootComponent.rootBottomSheetComponent

setContent {
Expand All @@ -51,7 +52,7 @@ class MainActivity : ComponentActivity() {
}
}
}
ComposeApplication(rootModule.themeSwitcher.value) {
ComposeApplication(rootModule.themeSwitcherComponent.value) {
ModalBottomSheetLayout(
sheetState = bottomSheetState.sheetState,
sheetContent = bottomSheetState.sheetContent.value,
Expand All @@ -60,7 +61,6 @@ class MainActivity : ComponentActivity() {
) {
ApplicationContent(
rootComponent = rootComponent,
rootBottomSheetComponent = rootBottomSheetComponent,
modifier = Modifier
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,86 @@
package com.makeevrserg.empireprojekt.mobile.application

import android.app.Application
import android.content.Context
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.data.WearDataLayerRegistry
import com.google.firebase.ktx.Firebase
import com.google.firebase.ktx.initialize
import com.makeevrserg.empireprojekt.mobile.features.root.di.RootModule
import com.makeevrserg.empireprojekt.mobile.features.root.di.impl.RootModuleImpl
import com.makeevrserg.empireprojekt.mobile.wear.messenger.di.WearMessengerModule
import com.makeevrserg.empireprojekt.mobile.work.CheckStatusWork
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import ru.astrainteractive.klibs.kdi.getValue
import ru.astrainteractive.klibs.mikro.platform.DefaultAndroidPlatformConfiguration
import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.seconds

@OptIn(ExperimentalHorologistApi::class)
class App : Application() {
private val servicesModule by RootModule.servicesModule
val rootModule by lazy {
RootModuleImpl()
}
val wearMessengerModule by lazy {
WearMessengerModule.Default(
context = rootModule.servicesModule.platformConfiguration.value.applicationContext,
coroutineScope = rootModule.servicesModule.mainScope.value,
json = rootModule.servicesModule.jsonConfiguration.value
)
}
private val wearDataLayerRegistry by lazy {
WearDataLayerRegistry.fromContext(
application = applicationContext,
coroutineScope = rootModule.servicesModule.mainScope.value
)
}
private val messageClient by lazy {
wearDataLayerRegistry.messageClient
}

override fun onTerminate() {
super.onTerminate()
rootModule.servicesModule.mainScope.value.cancel()
}

override fun onCreate() {
super.onCreate()
Firebase.initialize(this)
servicesModule.platformConfiguration.initialize(
rootModule.servicesModule.platformConfiguration.initialize {
DefaultAndroidPlatformConfiguration(
applicationContext
)
)
}
scheduleWork()
}

private fun scheduleWork() {
val statusWork = PeriodicWorkRequest.Builder(
CheckStatusWork::class.java,
15,
TimeUnit.MINUTES
).build()
val instanceWorkManager = WorkManager.getInstance(applicationContext)

rootModule.servicesModule.mainScope.value.launch {
while (isActive) {
instanceWorkManager.enqueueUniquePeriodicWork(
CheckStatusWork::class.java.simpleName,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
statusWork
)
delay(30.seconds)
}
}
}

companion object {
fun Application.asEmpireApp(): App = (this as App)
fun Context.asEmpireApp(): App = (applicationContext as App)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.makeevrserg.empireprojekt.mobile.work

import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.makeevrserg.empireprojekt.mobile.application.App.Companion.asEmpireApp
import com.makeevrserg.empireprojekt.mobile.features.status.StatusComponent
import com.makeevrserg.empireprojekt.mobile.wear.messenger.api.app.model.StatusModel
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import ru.astrainteractive.klibs.kdi.Provider
import ru.astrainteractive.klibs.kdi.getValue

class CheckStatusWork(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
private val wearMessengerModule by lazy {
applicationContext.asEmpireApp().wearMessengerModule
}
private val rootModule by lazy {
applicationContext.asEmpireApp().rootModule
}
private val rootStatusComponent by Provider {
rootModule.rootStatusComponent.value
}

override suspend fun doWork(): Result {
Log.d(TAG, "doWork: ")
sendStatus()
return Result.success()
}

private suspend fun sendStatus() = coroutineScope {
val messages = rootStatusComponent.statusComponents.map {
async {
it.checkStatus()
val model = it.model.value
StatusModel(
title = model.title.toString(applicationContext),
isLoading = model.isLoading,
status = when (model.status) {
StatusComponent.Model.LoadingStatus.LOADING -> StatusModel.LoadingStatus.LOADING
StatusComponent.Model.LoadingStatus.SUCCESS -> StatusModel.LoadingStatus.SUCCESS
StatusComponent.Model.LoadingStatus.ERROR -> StatusModel.LoadingStatus.ERROR
}
)
}
}.awaitAll()
wearMessengerModule.wearMessageProducer.produce(
message = wearMessengerModule.statusModelMessage,
value = messages
)
}

companion object {
private const val TAG = "CheckStatusWork"
}
}
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ makeevrserg.android.sdk.target=34
# Project
makeevrserg.project.name=EmpireProjektMobile
makeevrserg.project.group=com.makeevrserg.empireprojekt.mobile
makeevrserg.project.version.string=0.0.3
makeevrserg.project.version.code=5
makeevrserg.project.version.string=0.1.0
makeevrserg.project.version.code=6
makeevrserg.project.description=EmpireProjekt mobile application
makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com
makeevrserg.project.url=https://empireprojekt.ru
Expand Down
6 changes: 3 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]
# Kotlin
kotlin-version = "1.8.20"
kotlin-version = "1.9.0"
kotlin-dokka = "1.8.10"
kotlin-coroutines = "1.7.2"
kotlin-compilerExtensionVersion = "1.4.5"
kotlin-compilerExtensionVersion = "1.5.1"
kotlin-android-application = "8.0.1"
kotlin-serialization-json = "1.5.1"

Expand Down Expand Up @@ -55,7 +55,7 @@ klibs-kstorage = "1.0.0"
klibs-kdi = "1.1.0"

# Compose
kotlin-compose = "1.4.0"
kotlin-compose = "1.4.3"

# Moko
moko-mvvm = "0.16.1"
Expand Down
Binary file not shown.
6 changes: 3 additions & 3 deletions iosApp/iosApp/Presentation/Root/RootHolder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ final class RootHolder {

init() {
lifecycle = LifecycleRegistryKt.LifecycleRegistry()
let platformConfiguration = DefaultIosPlatformConfiguration()
ServicesModuleCompanion.shared.platformConfiguration.initialize(value: platformConfiguration)
let platformConfiguration = DefaultNativePlatformConfiguration()
RootModuleCompanion.shared.servicesModule.platformConfiguration.initialize(value: platformConfiguration)
root = DefaultRootComponent(
componentContext: DefaultComponentContext(lifecycle: lifecycle),
rootModule: RootModuleCompanion.shared,
servicesModule: ServicesModuleCompanion.shared
servicesModule: RootModuleCompanion.shared.servicesModule
)
lifecycle.onCreate()
}
Expand Down
2 changes: 1 addition & 1 deletion iosApp/iosApp/Presentation/Root/RootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private struct ChildView: View {
case let child as DefaultRootComponentConfigurationSplash:
SplashView(root, child.splashComponent)
case let child as DefaultRootComponentConfigurationStatus:
StatusView(root, child.statusComponents)
StatusView(root, child.rootStatusComponent)
default:
EmptyView()
}
Expand Down
8 changes: 4 additions & 4 deletions iosApp/iosApp/Presentation/Status/StatusView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import Root

struct StatusView: View {
let rootComponent: RootComponent
let statusComponents: [StatusComponent]
let statusComponent: RootStatusComponent

init(_ rootComponent: RootComponent, _ statusComponents: [StatusComponent]) {
self.statusComponents = statusComponents
init(_ rootComponent: RootComponent, _ statusComponent: RootStatusComponent) {
self.statusComponent = statusComponent
self.rootComponent = rootComponent
}
var body: some View {
Expand All @@ -27,7 +27,7 @@ struct StatusView: View {
Text(MR.strings.shared.status_subtitle.desc().localized())
.font(.body)

List(statusComponents,id: \.model.description) { statusComponent in
List(statusComponent.statusComponents,id: \.model.description) { statusComponent in
StatusWidget(statusComponent)
}.listStyle(.inset)
}
Expand Down
Loading

0 comments on commit 6d6d87b

Please sign in to comment.