├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── deploymentTargetDropDown.xml ├── git_toolbox_prj.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml ├── migrations.xml └── vcs.xml ├── LICENSE ├── Parts Diagram.dia ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── kortisan │ │ └── demoapp │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── kortisan │ │ │ └── demoapp │ │ │ ├── DemoAppKoreApplication.kt │ │ │ └── StartActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ ├── data_extraction_rules.xml │ │ ├── voice_interaction_service.xml │ │ └── voice_interaction_service_directions.xml │ └── test │ └── java │ └── com │ └── kortisan │ └── demoapp │ └── ExampleUnitTest.kt ├── authentication ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── kortisan │ │ └── authentication │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── kortisan │ │ └── authentication │ │ ├── domain │ │ ├── AuthenticationViewModel.kt │ │ └── models │ │ │ ├── AskForEmailModel.kt │ │ │ ├── AskForPasswordModel.kt │ │ │ └── ReadBiometricsModel.kt │ │ └── presentation │ │ ├── AuthenticationMainActivity.kt │ │ ├── AuthenticationSceneBuilder.kt │ │ ├── actions │ │ └── SetTextAction.kt │ │ ├── blocs │ │ ├── AskForEmailBloc.kt │ │ ├── AskForPasswordBloc.kt │ │ ├── LoginBloc.kt │ │ └── ReadBiometricsBloc.kt │ │ └── states │ │ ├── AskForEmailState.kt │ │ └── productionRules │ │ └── AskForEmailProductionRules.kt │ └── test │ └── java │ └── com │ └── kortisan │ └── authentication │ └── ExampleUnitTest.kt ├── build.gradle ├── content ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── kortisan │ │ └── content │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── kortisan │ │ │ └── content │ │ │ ├── domain │ │ │ ├── MainActivityViewModel.kt │ │ │ └── models │ │ │ │ └── DashboardModel.kt │ │ │ └── presentation │ │ │ ├── MainActivity.kt │ │ │ ├── blocs │ │ │ └── DashboardBloc.kt │ │ │ ├── states │ │ │ └── NotificationTextState.kt │ │ │ └── tagging │ │ │ └── MainActivitySceneBuilder.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── baseline_face_24.xml │ │ └── ic_launcher_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── kortisan │ └── content │ └── ExampleUnitTest.kt ├── fileTemplates ├── Business Logic Component (BLoC).kt ├── Business Logic Component (BLoC).kt.child.0.kt ├── Business Logic Component (BLoC).kt.child.1.kt ├── Business Logic Component (BLoC).kt.child.2.kt ├── Business Logic Component (BLoC).kt.child.3.kt ├── Business Logic Component (BLoC).kt.child.4.kt ├── Content Caretaker.kt ├── Framework Gate.kt ├── KSP Annotation.kt ├── KSP Annotation.kt.child.0.kt ├── KSP Annotation.kt.child.1.kt ├── Storage Local BD.kt ├── Storage Local Datastore.kt ├── Storage Remote Service.kt ├── Storage Repository.kt ├── Storage Security Strategy.kt ├── ViewModel with ActionDispatcher.kt ├── ViewModel with ActionDispatcher.kt.child.0.kt └── includes │ └── File Header.java ├── framework ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── kortisan │ │ └── framework │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── kortisan │ │ │ └── framework │ │ │ ├── ApplicationExtensionFunctions.kt │ │ │ ├── FrameworkApplicationBinding.kt │ │ │ ├── bloc │ │ │ ├── BaseBloc.kt │ │ │ ├── BaseUseCase.kt │ │ │ ├── BlocState.kt │ │ │ ├── ReduxViewModelBase.kt │ │ │ ├── ReduxViewModelFactory.kt │ │ │ ├── Resource.kt │ │ │ ├── SingleActivityWithViewModel.kt │ │ │ └── ViewModelActionDispatcher.kt │ │ │ ├── entities │ │ │ ├── Address.kt │ │ │ ├── Device.kt │ │ │ ├── DynamicKeys.kt │ │ │ └── Tokens.kt │ │ │ ├── entrypoints │ │ │ ├── ActorProviderStrategy.kt │ │ │ ├── AppLinksEntrypointStrategy.kt │ │ │ ├── ClevertapEntrypointStrategy.kt │ │ │ ├── ComposeNavigationEntrypointStrategy.kt │ │ │ ├── DeeplinkEntrypointStrategy.kt │ │ │ ├── EntrypointStrategy.kt │ │ │ ├── GoogleAssistantEntrypointStrategy.kt │ │ │ ├── IntentEntrypointStrategy.kt │ │ │ ├── OneLinkEntrypointStrategy.kt │ │ │ ├── PushNotificationEntrypointStrategy.kt │ │ │ └── ShortcutEntrypointStrategy.kt │ │ │ ├── redux │ │ │ ├── ApplicationActionDispatcher.kt │ │ │ ├── actions │ │ │ │ ├── BiometricsActions.kt │ │ │ │ ├── DefaultErrorAction.kt │ │ │ │ ├── EnrollmentActions.kt │ │ │ │ ├── EventsActions.kt │ │ │ │ ├── ExitGateAction.kt │ │ │ │ ├── GeopositionActions.kt │ │ │ │ ├── LoadStateAction.kt │ │ │ │ ├── NavigationActions.kt │ │ │ │ ├── NotificationActions.kt │ │ │ │ ├── PerformanceScoreActions.kt │ │ │ │ ├── ReDispatchAction.kt │ │ │ │ ├── ReduxAction.kt │ │ │ │ ├── RemoteConfigActions.kt │ │ │ │ ├── RevertAction.kt │ │ │ │ ├── SensorsActions.kt │ │ │ │ ├── UpdateActions.kt │ │ │ │ └── wrappers │ │ │ │ │ ├── ActionEventInstance.kt │ │ │ │ │ ├── AttachedEventsInterface.kt │ │ │ │ │ └── AttatchEventWrapper.kt │ │ │ ├── controllers │ │ │ │ ├── ControllersProxy.kt │ │ │ │ ├── ReduxControllerAbstract.kt │ │ │ │ ├── ReduxControllerState.kt │ │ │ │ ├── errorHandler │ │ │ │ │ └── ShowErrorActivity.kt │ │ │ │ ├── gates │ │ │ │ │ ├── BaseGate.kt │ │ │ │ │ ├── ExitGateResult.kt │ │ │ │ │ └── GatesController.kt │ │ │ │ ├── geoposition │ │ │ │ │ └── GeopositionController.kt │ │ │ │ ├── navigation │ │ │ │ │ ├── FlowNameAlias.kt │ │ │ │ │ ├── NavigationController.kt │ │ │ │ │ ├── PrimitiveTargetActivityIdentifier.kt │ │ │ │ │ ├── contracts │ │ │ │ │ │ ├── CustomActivityContract.kt │ │ │ │ │ │ ├── ReduxActivityResultContract.kt │ │ │ │ │ │ └── ResultContractStatus.kt │ │ │ │ │ ├── protocol │ │ │ │ │ │ ├── DefaultParams.kt │ │ │ │ │ │ ├── NavigationTarget.kt │ │ │ │ │ │ └── StartComposeDestination.kt │ │ │ │ │ ├── routeExplorer │ │ │ │ │ │ ├── NavigationDirectories.kt │ │ │ │ │ │ └── RouteExplorer.kt │ │ │ │ │ ├── strategies │ │ │ │ │ │ └── NavigationStrategy.kt │ │ │ │ │ └── targets │ │ │ │ │ │ ├── AuthenticationNavigationGroup.kt │ │ │ │ │ │ ├── DashboardNavigationGroup.kt │ │ │ │ │ │ ├── NavigationTargetGroup.kt │ │ │ │ │ │ ├── NavigationTargetParams.kt │ │ │ │ │ │ ├── SealedActivityClassList.kt │ │ │ │ │ │ ├── TargetActivity.kt │ │ │ │ │ │ ├── TargetClass.kt │ │ │ │ │ │ ├── TargetCompose.kt │ │ │ │ │ │ └── TargetExternal.kt │ │ │ │ ├── notifications │ │ │ │ │ ├── FirebaseMessagingDecorator.kt │ │ │ │ │ ├── FirebaseMessagingReceiver.kt │ │ │ │ │ ├── NotificationChannel.kt │ │ │ │ │ └── PushNotificationController.kt │ │ │ │ ├── performanceScrore │ │ │ │ │ └── CalculatePerformanceController.kt │ │ │ │ ├── remoteConfig │ │ │ │ │ ├── RemoteConfigController.kt │ │ │ │ │ └── parsers │ │ │ │ │ │ ├── FlowNameAliasRemoteConfig.kt │ │ │ │ │ │ ├── RemoteConfigDirectoryMap.kt │ │ │ │ │ │ └── TaggingSettingsRemoteConfig.kt │ │ │ │ ├── securityAssets │ │ │ │ │ ├── BiometricPromptActivity.kt │ │ │ │ │ └── SecurityAssetsController.kt │ │ │ │ ├── sensors │ │ │ │ │ └── SensorsController.kt │ │ │ │ ├── tagging │ │ │ │ │ ├── SceneBuilderBase.kt │ │ │ │ │ ├── TaggingController.kt │ │ │ │ │ ├── builders │ │ │ │ │ │ └── EntryPointSceneBuilder.kt │ │ │ │ │ ├── decorators │ │ │ │ │ │ ├── AttachEventDecorator.kt │ │ │ │ │ │ ├── SceneBaseDecorator.kt │ │ │ │ │ │ ├── SceneDecoratorInterface.kt │ │ │ │ │ │ └── application │ │ │ │ │ │ │ └── SensorsTaggingDecorator.kt │ │ │ │ │ └── providers │ │ │ │ │ │ ├── FirebaseTaggingStrategy.kt │ │ │ │ │ │ └── TaggingStrategy.kt │ │ │ │ └── updatesController │ │ │ │ │ └── UpdatesController.kt │ │ │ ├── gates │ │ │ │ ├── AskForEmailGate.kt │ │ │ │ ├── CheckUpdateGate.kt │ │ │ │ ├── FingerprintGate.kt │ │ │ │ ├── LoggedGate.kt │ │ │ │ └── PasswordAuthorizationGate.kt │ │ │ ├── middleware │ │ │ │ ├── BiometricsMiddleware.kt │ │ │ │ ├── CalculatePerformanceScoreMiddleware.kt │ │ │ │ ├── ErrorHandlerMiddleware.kt │ │ │ │ ├── GatesMiddleware.kt │ │ │ │ ├── MiddlewareInterface.kt │ │ │ │ ├── NavigationMiddleware.kt │ │ │ │ ├── NotificationMiddleware.kt │ │ │ │ ├── PositionMiddleware.kt │ │ │ │ ├── RemoteConfigMiddleware.kt │ │ │ │ ├── SensorsMiddleware.kt │ │ │ │ ├── TaggingMiddleware.kt │ │ │ │ └── UpdatesMiddleware.kt │ │ │ ├── state │ │ │ │ ├── ConnectivityState.kt │ │ │ │ ├── DeviceState.kt │ │ │ │ ├── GeopositionState.kt │ │ │ │ ├── NavigationState.kt │ │ │ │ ├── PerformanceScoreState.kt │ │ │ │ ├── PermissionState.kt │ │ │ │ ├── ReduxState.kt │ │ │ │ ├── RemoteConfigState.kt │ │ │ │ ├── RouteFlowNamesAliasState.kt │ │ │ │ ├── SensorsState.kt │ │ │ │ ├── SessionState.kt │ │ │ │ ├── UpdateState.kt │ │ │ │ ├── caretaker │ │ │ │ │ ├── CaretakerStrategy.kt │ │ │ │ │ ├── DatastoreCaretakerStrategy.kt │ │ │ │ │ ├── FileCaretakerStrategy.kt │ │ │ │ │ └── RoomCaretakerStrategy.kt │ │ │ │ ├── productionrules │ │ │ │ │ ├── ProductionRule.kt │ │ │ │ │ └── dsl │ │ │ │ │ │ └── ProductionRuleDSL.kt │ │ │ │ └── validations │ │ │ │ │ ├── StateValidationResult.kt │ │ │ │ │ ├── ValidationBuilder.kt │ │ │ │ │ ├── ValidationRule.kt │ │ │ │ │ └── rules │ │ │ │ │ ├── ValidateEmailFormatRule.kt │ │ │ │ │ ├── ValidateMinLengthRule.kt │ │ │ │ │ └── ValidateNotEmptyRule.kt │ │ │ └── stores │ │ │ │ └── ApplicationStateStore.kt │ │ │ ├── services │ │ │ ├── location │ │ │ │ └── KoreLocationService.kt │ │ │ ├── mediaplayer │ │ │ │ └── MediaPlayerService.kt │ │ │ └── voiceinteraction │ │ │ │ ├── VoiceCommandInteractionService.kt │ │ │ │ ├── VoiceCommandInteractionSession.kt │ │ │ │ └── VoiceCommandInteractionSessionService.kt │ │ │ └── storage │ │ │ ├── local │ │ │ ├── database │ │ │ │ ├── TypeConverters.kt │ │ │ │ └── dao │ │ │ │ │ ├── BaseDao.kt │ │ │ │ │ └── SecurityLayerDao.kt │ │ │ └── datastore │ │ │ │ ├── DataStoreBinding.kt │ │ │ │ ├── DataStoreSecureInterface.kt │ │ │ │ ├── serializers │ │ │ │ ├── DynamicKeysVaultStoreSerializer.kt │ │ │ │ └── TokensVaultStoreSerializer.kt │ │ │ │ └── vaults │ │ │ │ ├── DynamicKeysVaultStoreSecure.kt │ │ │ │ └── TokensVaultStoreSecure.kt │ │ │ ├── remote │ │ │ └── webservices │ │ │ │ ├── client │ │ │ │ ├── ApiClient.kt │ │ │ │ ├── EndPoints.kt │ │ │ │ ├── interceptors │ │ │ │ │ ├── apiInterfaces │ │ │ │ │ │ └── AuthenticationApiInterface.kt │ │ │ │ │ ├── application │ │ │ │ │ │ ├── AuthInterceptor.kt │ │ │ │ │ │ └── HttpCodeInterceptor.kt │ │ │ │ │ └── network │ │ │ │ │ │ └── Retry.kt │ │ │ │ └── strategies │ │ │ │ │ ├── ClientBuilderStrategy.kt │ │ │ │ │ └── NoInterceptorStrategy.kt │ │ │ │ └── dto │ │ │ │ ├── BaseRequest.kt │ │ │ │ ├── BaseResponse.kt │ │ │ │ └── PersistentResponseInterface.kt │ │ │ ├── repositories │ │ │ ├── RepositoryStrategy.kt │ │ │ └── RepositoryUtils.kt │ │ │ └── security │ │ │ ├── AesStrategy.kt │ │ │ ├── NativeKeysAccess.kt │ │ │ ├── NoSecurityStrategy.kt │ │ │ └── SecurityStrategy.kt │ ├── proto │ │ ├── DynamicKeysVaultStore.proto │ │ └── TokensVaultStore.proto │ └── res │ │ ├── drawable │ │ └── error_24.xml │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── kortisan │ └── framework │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── ksp ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── kortisan │ │ └── ksp │ │ └── annotations │ │ ├── FlowNameActivity.kt │ │ ├── FlowNameClass.kt │ │ ├── FlowNameCompose.kt │ │ ├── FlowNameExternal.kt │ │ ├── FlowNameProcessor.kt │ │ └── FlowNameProcessorProvider.kt │ └── resources │ └── META-INF │ └── services │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider ├── projectBuildSettings ├── dependencyHierarchy.gradle ├── detectAndJoinKSP.gradle ├── projectBuild.gradle ├── projectBuildTypes.gradle ├── projectConfig.gradle ├── projectDependencies.gradle ├── projectDependenciesFramework.gradle ├── projectFlavors.gradle └── protobufSettings.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | /.idea/misc.xml 11 | /.idea/sonarlint/issuestore/index.pb 12 | .DS_Store 13 | /build 14 | /captures 15 | .externalNativeBuild 16 | .cxx 17 | local.properties 18 | /.idea/sonarlint/ 19 | 20 | # Kotlin 2.0 21 | .kotlin/ -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | DemoAppKoreFrame -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/git_toolbox_prj.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 13 | 14 | 16 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Jacobo Gonzalez Tamayo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Parts Diagram.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/Parts Diagram.dia -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias( libs.plugins.android.application ) 3 | alias( libs.plugins.kotlin.android ) 4 | alias( libs.plugins.devtools.ksp ) 5 | alias( libs.plugins.compose.compiler ) 6 | } 7 | 8 | apply from: "$rootDir.path/projectBuildSettings/projectBuild.gradle" 9 | def config = ext.projectGradleConfig 10 | 11 | android { 12 | namespace 'com.kortisan.demoapp' 13 | compileSdk config.compileSdkVersion 14 | 15 | defaultConfig { 16 | applicationId config.applicationId 17 | minSdk config.minSdkVersion 18 | targetSdk config.targetSdkVersion 19 | 20 | version getVersionName() 21 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 22 | multiDexEnabled true 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation project(path: ':content') 28 | implementation project(path: ':framework') 29 | // Only for StartActivity 30 | implementation libs.appcompat 31 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/kortisan/demoapp/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.demoapp 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import androidx.test.platform.app.InstrumentationRegistry 8 | import androidx.test.ext.junit.runners.AndroidJUnit4 9 | 10 | import org.junit.Test 11 | import org.junit.runner.RunWith 12 | 13 | import org.junit.Assert.* 14 | 15 | /** 16 | * Instrumented test, which will execute on an Android device. 17 | * 18 | * See [testing documentation](http://d.android.com/tools/testing). 19 | */ 20 | @RunWith(AndroidJUnit4::class) 21 | class ExampleInstrumentedTest { 22 | @Test 23 | fun useAppContext() { 24 | // Context of the app under test. 25 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 26 | assertEquals("com.kortisan.demoapp", appContext.packageName) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/kortisan/demoapp/DemoAppKoreApplication.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.demoapp 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.FrameworkApplicationBinding 8 | 9 | class DemoAppKoreApplication: FrameworkApplicationBinding() -------------------------------------------------------------------------------- /app/src/main/java/com/kortisan/demoapp/StartActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.demoapp 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.kortisan.framework.entrypoints.IntentEntrypointStrategy 6 | import com.kortisan.framework.redux.ApplicationActionDispatcher 7 | import com.kortisan.framework.redux.actions.NavigationActions 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | import com.kortisan.framework.redux.controllers.ControllersProxy 10 | import com.kortisan.framework.redux.controllers.navigation.NavigationController 11 | import com.kortisan.framework.redux.gates.AskForEmailGate 12 | import com.kortisan.framework.redux.gates.FingerprintGate 13 | import com.kortisan.framework.redux.gates.LoggedGate 14 | 15 | class StartActivity: AppCompatActivity() { 16 | private val navigationController = ControllersProxy.getController() 17 | 18 | override fun onCreate(savedInstanceState: Bundle?) { 19 | super.onCreate(savedInstanceState) 20 | 21 | var startAction = IntentEntrypointStrategy( intent ).getAction() 22 | 23 | if( startAction is ReduxAction.EmptyAction ) 24 | navigationController?.defaultNavigationTarget?.also { 25 | startAction = NavigationActions.NavigateToTarget( it ) 26 | } 27 | 28 | finishAffinity() 29 | 30 | // Despachamos una acción al bus de eventos sin que repercuta en una vista 31 | ApplicationActionDispatcher.dispatch ( startAction.apply { 32 | // Aplicamos la compuerta que comprueba el estado de login del usuario 33 | //gates = listOf( LoggedGate ) 34 | } 35 | ) 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DemoApp 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/xml/voice_interaction_service.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/xml/voice_interaction_service_directions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Para buscar un producto en la aplicación, di "Ok Google" seguido de tu búsqueda. 5 | Por ejemplo, puedes decir "Ok Google, busca zapatillas de running" para encontrar zapatillas de running disponibles para la compra. 6 | También puedes decir "Ok Google, muestra el carrito de compras" para ver el contenido de tu carrito de compras. 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/test/java/com/kortisan/demoapp/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.demoapp 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import org.junit.Test 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Example local unit test, which will execute on the development machine (host). 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | class ExampleUnitTest { 17 | @Test 18 | fun addition_isCorrect() { 19 | assertEquals(4, 2 + 2) 20 | } 21 | } -------------------------------------------------------------------------------- /authentication/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /authentication/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'kotlin-kapt' 5 | alias( libs.plugins.devtools.ksp ) 6 | alias( libs.plugins.compose.compiler ) 7 | } 8 | 9 | apply from: "$rootDir.path/projectBuildSettings/projectBuild.gradle" 10 | def config = ext.projectGradleConfig 11 | 12 | android { 13 | namespace 'com.kortisan.authentication' 14 | compileSdk config.compileSdkVersion 15 | compileSdkVersion config.compileSdkVersion 16 | 17 | defaultConfig { 18 | minSdk config.minSdkVersion 19 | targetSdk config.targetSdkVersion 20 | targetSdkVersion config.targetSdkVersion 21 | compileSdk config.compileSdkVersion 22 | compileSdkVersion config.compileSdkVersion 23 | version getVersionName() 24 | 25 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 26 | 27 | multiDexEnabled true 28 | consumerProguardFiles "consumer-rules.pro" 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation project(path: ':framework') 34 | 35 | // KSP Annotation processor 36 | implementation project(path: ':ksp') 37 | ksp project(":ksp") 38 | } -------------------------------------------------------------------------------- /authentication/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/authentication/consumer-rules.pro -------------------------------------------------------------------------------- /authentication/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /authentication/src/androidTest/java/com/kortisan/authentication/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.kortisan.authentication.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /authentication/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/domain/models/AskForEmailModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.domain.models 2 | 3 | data class AskForEmailModel(val email: String = "") 4 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/domain/models/AskForPasswordModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.domain.models 2 | 3 | data class AskForPasswordModel(val id: Any? = null) 4 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/domain/models/ReadBiometricsModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.domain.models 2 | 3 | data class ReadBiometricsModel(val id: Any? = null) 4 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/AuthenticationSceneBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.SceneBuilderBase 4 | 5 | class AuthenticationSceneBuilder private constructor(): SceneBuilderBase() { 6 | class Builder: SceneBuilderBase.Builder() { 7 | override val taggingScene: SceneBuilderBase = AuthenticationSceneBuilder() 8 | fun setCurrentFlow( name: String ) = apply { 9 | taggingScene.baseParams["currentFlowName"] = name 10 | } 11 | } 12 | 13 | override fun getData(): Map = baseParams 14 | } 15 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/actions/SetTextAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation.actions 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | 5 | data class SetTextAction( 6 | val newText: String 7 | ): ReduxAction() 8 | -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/blocs/AskForPasswordBloc.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation.blocs 2 | 3 | import androidx.compose.material3.Text 4 | import androidx.compose.runtime.Composable 5 | import com.kortisan.authentication.domain.models.AskForPasswordModel 6 | import com.kortisan.framework.bloc.BaseBloc 7 | import com.kortisan.framework.bloc.BlocState 8 | import com.kortisan.framework.bloc.ViewModelActionDispatcher 9 | 10 | class AskForPasswordBloc ( 11 | override val viewModelActionDispatcher: ViewModelActionDispatcher, 12 | override val state: BlocState 13 | ): BaseBloc( 14 | viewModelActionDispatcher, state 15 | ) { 16 | @Composable 17 | override fun Render() { 18 | Text("AskForPasswordBloc") 19 | } 20 | } -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/blocs/LoginBloc.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation.blocs 2 | 3 | import androidx.compose.foundation.layout.Column 4 | import androidx.compose.material3.Button 5 | import androidx.compose.material3.Text 6 | import androidx.compose.runtime.Composable 7 | import com.kortisan.framework.bloc.BaseBloc 8 | import com.kortisan.framework.bloc.BlocState 9 | import com.kortisan.framework.bloc.ViewModelActionDispatcher 10 | import com.kortisan.framework.redux.actions.NavigationActions 11 | import com.kortisan.framework.redux.controllers.navigation.targets.AuthenticationNavigationGroup 12 | 13 | class LoginBloc( 14 | override val viewModelActionDispatcher: ViewModelActionDispatcher, 15 | override val state: BlocState 16 | ): BaseBloc( 17 | viewModelActionDispatcher, state 18 | ) { 19 | @Composable 20 | override fun Render() { 21 | Column() { 22 | Text(text = "LoginBloc") 23 | Button(onClick = { 24 | // Enviamos una acción al despachador del viewModel de la actividad actual 25 | viewModelActionDispatcher.dispatch( 26 | NavigationActions.NavigateToTarget( 27 | AuthenticationNavigationGroup.Authentication.AskForEmailCompose 28 | ) 29 | ) 30 | }) { 31 | Text(text = "GOTO AskFor Email") 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/blocs/ReadBiometricsBloc.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation.blocs 2 | 3 | import androidx.compose.material3.Text 4 | import androidx.compose.runtime.Composable 5 | import com.kortisan.authentication.domain.models.ReadBiometricsModel 6 | import com.kortisan.framework.bloc.BaseBloc 7 | import com.kortisan.framework.bloc.BlocState 8 | import com.kortisan.framework.bloc.ViewModelActionDispatcher 9 | 10 | class ReadBiometricsBloc( 11 | override val viewModelActionDispatcher: ViewModelActionDispatcher, 12 | override val state: BlocState 13 | ): BaseBloc( 14 | viewModelActionDispatcher, state 15 | ) { 16 | @Composable 17 | override fun Render() { 18 | Text(text = "ReadBiometricsBloc") 19 | } 20 | } -------------------------------------------------------------------------------- /authentication/src/main/java/com/kortisan/authentication/presentation/states/AskForEmailState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication.presentation.states 2 | 3 | import com.kortisan.authentication.presentation.states.productionRules.AskForEmailProductionRules 4 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 5 | import com.kortisan.framework.redux.state.ReduxState 6 | 7 | /** 8 | * Estado que almacena el Email y valida que sea correcto 9 | * Usa la validación de longitud, formato y que no sea vacío. 10 | */ 11 | sealed class AskForEmailState: ReduxState() { 12 | /** 13 | * En este caso particular se comparten las mismas reglas de producción 14 | */ 15 | protected val sharedProductionRules = AskForEmailProductionRules.sharedProductionRules 16 | 17 | data object EmptyInput: AskForEmailState() { 18 | override val productionRules: List = sharedProductionRules 19 | } 20 | 21 | data class ErrorOnInput( 22 | val currentValue: String, 23 | val errorMessage: String 24 | ): AskForEmailState() { 25 | override val productionRules: List = sharedProductionRules 26 | } 27 | 28 | data class SuccessInput( 29 | val currentValue: String 30 | ): AskForEmailState() { 31 | override val productionRules: List = sharedProductionRules 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /authentication/src/test/java/com/kortisan/authentication/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.authentication 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | //classpath libs.aws.android.sdk.appsync.gradle.plugin 4 | classpath libs.google.services 5 | classpath libs.firebase.crashlytics.gradle 6 | classpath libs.perf.plugin 7 | classpath libs.protobuf.gradle.plugin 8 | classpath libs.kotlin.gradle.plugin 9 | classpath libs.kotlin.serialization.plugin 10 | classpath libs.kotlin.gradle.build 11 | } 12 | repositories { 13 | mavenCentral() 14 | } 15 | } 16 | 17 | plugins { 18 | id 'com.android.application' version libs.versions.androidApplicationVer apply false 19 | id 'com.android.library' version libs.versions.androidApplicationVer apply false 20 | id 'org.jetbrains.kotlin.android' version libs.versions.kotlinVersion apply false 21 | id 'com.google.devtools.ksp' version libs.versions.ksp apply false 22 | } 23 | 24 | tasks.register('clean', Delete) { 25 | delete rootProject.buildDir 26 | } 27 | -------------------------------------------------------------------------------- /content/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /content/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'kotlin-kapt' 5 | alias( libs.plugins.devtools.ksp ) 6 | alias( libs.plugins.compose.compiler ) 7 | } 8 | 9 | apply from: "$rootDir.path/projectBuildSettings/projectBuild.gradle" 10 | def config = ext.projectGradleConfig 11 | 12 | android { 13 | namespace 'com.kortisan.content' 14 | compileSdk config.compileSdkVersion 15 | compileSdkVersion config.compileSdkVersion 16 | 17 | defaultConfig { 18 | minSdk config.minSdkVersion 19 | targetSdk config.targetSdkVersion 20 | compileSdk config.compileSdkVersion 21 | compileSdkVersion config.compileSdkVersion 22 | version getVersionName() 23 | 24 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 25 | 26 | multiDexEnabled true 27 | consumerProguardFiles "consumer-rules.pro" 28 | } 29 | } 30 | 31 | dependencies { 32 | implementation project(path: ':framework') 33 | implementation project(path: ':authentication') 34 | 35 | // KSP Annotation processor 36 | implementation project(path: ':ksp') 37 | ksp project(":ksp") 38 | } -------------------------------------------------------------------------------- /content/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /content/src/androidTest/java/com/kortisan/content/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import androidx.test.platform.app.InstrumentationRegistry 8 | import androidx.test.ext.junit.runners.AndroidJUnit4 9 | 10 | import org.junit.Test 11 | import org.junit.runner.RunWith 12 | 13 | import org.junit.Assert.* 14 | 15 | /** 16 | * Instrumented test, which will execute on an Android device. 17 | * 18 | * See [testing documentation](http://d.android.com/tools/testing). 19 | */ 20 | @RunWith(AndroidJUnit4::class) 21 | class ExampleInstrumentedTest { 22 | @Test 23 | fun useAppContext() { 24 | // Context of the app under test. 25 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 26 | assertEquals("com.kortisan.content", appContext.packageName) 27 | } 28 | } -------------------------------------------------------------------------------- /content/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/src/main/java/com/kortisan/content/domain/MainActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content.domain 2 | 3 | import android.app.Application 4 | import com.kortisan.content.domain.models.DashboardModel 5 | import com.kortisan.content.presentation.blocs.DashboardBloc 6 | import com.kortisan.content.presentation.tagging.MainActivitySceneBuilder 7 | import com.kortisan.framework.bloc.BlocState 8 | import com.kortisan.framework.bloc.ReduxViewModelBase 9 | import com.kortisan.framework.bloc.ViewModelActionDispatcher 10 | import com.kortisan.framework.redux.stores.ApplicationStateStore 11 | import kotlinx.coroutines.flow.flow 12 | 13 | class MainActivityViewModel( 14 | application: Application, 15 | vmActionDispatcher: ViewModelActionDispatcher 16 | ): ReduxViewModelBase( application, vmActionDispatcher ) { 17 | private val mainActivitySceneBase = MainActivitySceneBuilder.Builder() 18 | .setModuleName("Main") 19 | .build() 20 | 21 | val dashboardRootBLoC = DashboardBloc( 22 | getDispatcher(), 23 | BlocState( 24 | ApplicationStateStore, 25 | mainActivitySceneBase, 26 | flow { emit(DashboardModel("FLOW VALUE")) } 27 | ) 28 | ) 29 | } -------------------------------------------------------------------------------- /content/src/main/java/com/kortisan/content/domain/models/DashboardModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content.domain.models 2 | 3 | data class DashboardModel( 4 | val texto: String 5 | ) -------------------------------------------------------------------------------- /content/src/main/java/com/kortisan/content/presentation/states/NotificationTextState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content.presentation.states 2 | 3 | import com.kortisan.framework.redux.actions.NotificationActions 4 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 5 | import com.kortisan.framework.redux.state.ReduxState 6 | 7 | sealed class NotificationTextState: ReduxState() { 8 | data class TextToShow( val currentShow: String ): NotificationTextState() { 9 | override val productionRules = sharedProductionRules 10 | } 11 | 12 | internal val sharedProductionRules = listOf( 13 | { state, action -> 14 | if( action is NotificationActions.ShowNotification ) 15 | TextToShow( "Mostrando notificacion" ) 16 | else state 17 | }, 18 | { state, action -> 19 | if( action is NotificationActions.HideAllNotifications ) 20 | TextToShow( "Notificaciones borradas" ) 21 | else state 22 | } 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /content/src/main/java/com/kortisan/content/presentation/tagging/MainActivitySceneBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content.presentation.tagging 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.SceneBuilderBase 4 | 5 | /** * * * * * * * * * 6 | * Project KoreFrame 7 | * Created by Jacobo G Tamayo on 01/01/23. 8 | * * * * * * * * * * **/ 9 | class MainActivitySceneBuilder private constructor(): SceneBuilderBase() { 10 | class Builder: SceneBuilderBase.Builder() { 11 | override val taggingScene: SceneBuilderBase = MainActivitySceneBuilder() 12 | 13 | fun setModuleName( moduleName: String ) = apply { 14 | taggingScene.baseParams["moduleName"] = moduleName 15 | } 16 | } 17 | 18 | override fun getData(): Map = baseParams 19 | } -------------------------------------------------------------------------------- /content/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /content/src/main/res/drawable/baseline_face_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /content/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /content/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /content/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /content/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/content/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /content/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /content/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /content/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Content 3 | Crear nota 4 | -------------------------------------------------------------------------------- /content/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /content/src/test/java/com/kortisan/content/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.content 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import org.junit.Test 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Example local unit test, which will execute on the development machine (host). 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | class ExampleUnitTest { 17 | @Test 18 | fun addition_isCorrect() { 19 | assertEquals(4, 2 + 2) 20 | } 21 | } -------------------------------------------------------------------------------- /fileTemplates/Business Logic Component (BLoC).kt.child.0.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.presentation.components#end 2 | 3 | import androidx.compose.material3.Text 4 | import androidx.compose.runtime.Composable 5 | 6 | #parse("File Header.java") 7 | @Composable 8 | fun Custom${NAME}Component( value: String ) { 9 | Text("Hello, I'am Custom${NAME}Component") 10 | Text(value) 11 | } -------------------------------------------------------------------------------- /fileTemplates/Business Logic Component (BLoC).kt.child.1.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.presentation.tagging.decorators#end 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneBaseDecorator 4 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface 5 | 6 | #parse("File Header.java") 7 | class ${NAME}SceneDecorator( 8 | override val sceneDecorator: SceneDecoratorInterface, 9 | // Option 1: Decorate from constructor 10 | val demoParam: String = "" 11 | ): SceneBaseDecorator() { 12 | init { 13 | decoratedValues["demoParam"] = demoParam 14 | } 15 | 16 | // Option 2: Decorate from builder 17 | fun setParam( demoParam: String ) = 18 | apply { 19 | decoratedValues["demoParam"] = demoParam 20 | } 21 | } -------------------------------------------------------------------------------- /fileTemplates/Business Logic Component (BLoC).kt.child.2.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.presentation.actions#end 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | 5 | #parse("File Header.java") 6 | sealed class ${NAME}Actions: ReduxAction() { 7 | data class SetCustomValue( val text: String, val number: Int ): ${NAME}Actions() 8 | data object RemoveValue: ${NAME}Actions() 9 | } -------------------------------------------------------------------------------- /fileTemplates/Business Logic Component (BLoC).kt.child.3.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.domain.models#end 2 | 3 | #parse("File Header.java") 4 | data class ${NAME}Model( 5 | val demoText: String = "Hello, I'am ${NAME}", 6 | val demoInt: Int = 123, 7 | ) -------------------------------------------------------------------------------- /fileTemplates/Business Logic Component (BLoC).kt.child.4.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.presentation.states#end 2 | 3 | import ${PACKAGE_NAME}.domain.models.${NAME}Model 4 | import ${PACKAGE_NAME}.presentation.actions.${NAME}Actions 5 | import com.kortisan.framework.redux.state.ProductionRule 6 | import com.kortisan.framework.redux.state.ReduxState 7 | 8 | #parse("File Header.java") 9 | sealed class ${NAME}State : ReduxState() { 10 | data class CustomValue( 11 | val currentValue: ${NAME}Model 12 | ) : ${NAME}State() { 13 | override val productionRules = sharedProductionRules 14 | } 15 | 16 | internal val sharedProductionRules = listOf( 17 | { state, action -> 18 | if (action is ${NAME}Actions.SetCustomValue) 19 | CustomValue( 20 | ${NAME}Model("I'am a value", 123) 21 | ) 22 | else state 23 | }, 24 | { state, action -> 25 | if (action is ${NAME}Actions.RemoveValue) 26 | CustomValue( 27 | ${NAME}Model("No value", 0) 28 | ) 29 | else state 30 | } 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /fileTemplates/Content Caretaker.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.state.caretakers#end 2 | 3 | import com.kortisan.framework.redux.state.caretaker.CaretakerStrategy 4 | import com.kortisan.framework.redux.state.ReduxState 5 | import com.kortisan.framework.storage.security.NoSecurityStrategy 6 | import com.kortisan.framework.storage.security.SecurityStrategy 7 | 8 | #parse("File Header.java") 9 | class ${NAME}CaretakerStrategy( 10 | override val defaultState: ${NAME}State 11 | ): CaretakerStrategy() { 12 | // Put the State data into a storage 13 | override fun persist(currentState: ${NAME}State) { 14 | TODO("Not yet implemented") 15 | } 16 | 17 | // Get the data from a storage and returns a State 18 | override fun recover(stateClassName: String): ${NAME}State? { 19 | TODO("Not yet implemented") 20 | } 21 | 22 | // How to protect the data 23 | override val securityStrategy: SecurityStrategy = NoSecurityStrategy 24 | } -------------------------------------------------------------------------------- /fileTemplates/Framework Gate.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.redux.gates#end 2 | 3 | import com.kortisan.framework.redux.actions.DefaultErrorAction 4 | import com.kortisan.framework.redux.actions.ReduxAction 5 | import com.kortisan.framework.redux.controllers.gates.BaseGate 6 | 7 | #parse("File Header.java") 8 | data object ${NAME}Gate: BaseGate() { 9 | override val startAction: ReduxAction = ReduxAction.EmptyAction 10 | 11 | override val onFailAction: ReduxAction 12 | get() = DefaultErrorAction("Can't continue, sorry :(") 13 | 14 | override fun enterInGate(startAction: ReduxAction): Boolean { 15 | return true 16 | } 17 | } -------------------------------------------------------------------------------- /fileTemplates/KSP Annotation.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end 2 | 3 | #parse("File Header.java") 4 | @Target( AnnotationTarget.CLASS ) 5 | @Retention( AnnotationRetention.SOURCE ) 6 | annotation class ${NAME}Annotation( 7 | val param1: String 8 | ) -------------------------------------------------------------------------------- /fileTemplates/KSP Annotation.kt.child.0.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | import com.google.devtools.ksp.processing.Dependencies 4 | import com.google.devtools.ksp.processing.Resolver 5 | import com.google.devtools.ksp.processing.SymbolProcessor 6 | import com.google.devtools.ksp.processing.SymbolProcessorEnvironment 7 | import com.google.devtools.ksp.symbol.KSAnnotated 8 | import com.google.devtools.ksp.symbol.KSClassDeclaration 9 | import com.google.devtools.ksp.validate 10 | import kotlin.reflect.KClass 11 | 12 | #parse("File Header.java") 13 | class ${NAME}Processor( 14 | private val environment: SymbolProcessorEnvironment 15 | ): SymbolProcessor { 16 | private fun Resolver.findAnnotations( 17 | kClass: KClass<*>, 18 | ) = getSymbolsWithAnnotation( 19 | kClass.qualifiedName.toString()) 20 | .filterIsInstance() 21 | 22 | override fun process(resolver: Resolver): List { 23 | val listedAnnotations: Sequence = 24 | resolver.findAnnotations(${NAME}Annotation::class) 25 | 26 | if( ! listedAnnotations.iterator().hasNext() ) 27 | return emptyList() 28 | 29 | val listedNames = listedAnnotations.map{ it.simpleName.asString() } 30 | 31 | val fileText = buildString { 32 | append("// ") 33 | append(listedNames.joinToString(", ")) 34 | } 35 | 36 | val file = environment 37 | .codeGenerator 38 | .createNewFile( 39 | Dependencies(false), 40 | "com.kortisan.framework.", 41 | "${NAME}Generated", 42 | ) 43 | 44 | file.write(fileText.toByteArray()) 45 | file.close() 46 | 47 | return (listedAnnotations).filterNot { it.validate() }.toList() 48 | } 49 | } -------------------------------------------------------------------------------- /fileTemplates/KSP Annotation.kt.child.1.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | import com.google.devtools.ksp.processing.SymbolProcessor 4 | import com.google.devtools.ksp.processing.SymbolProcessorEnvironment 5 | import com.google.devtools.ksp.processing.SymbolProcessorProvider 6 | 7 | #parse("File Header.java") 8 | class ${NAME}ProcessorProvider: SymbolProcessorProvider { 9 | override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { 10 | return ${NAME}Processor(environment) 11 | } 12 | } -------------------------------------------------------------------------------- /fileTemplates/Storage Local BD.kt: -------------------------------------------------------------------------------- 1 | // Storage Local BD DAO -------------------------------------------------------------------------------- /fileTemplates/Storage Local Datastore.kt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/fileTemplates/Storage Local Datastore.kt -------------------------------------------------------------------------------- /fileTemplates/Storage Remote Service.kt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/fileTemplates/Storage Remote Service.kt -------------------------------------------------------------------------------- /fileTemplates/Storage Repository.kt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/fileTemplates/Storage Repository.kt -------------------------------------------------------------------------------- /fileTemplates/Storage Security Strategy.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.storage.security#end 2 | 3 | #parse("File Header.java") 4 | 5 | /** 6 | * Estrategia de seguridad 7 | */ 8 | data object ${NAME}SecurityStrategy: SecurityStrategy() { 9 | override val transformation: String = "" 10 | 11 | override fun encrypt(value: String): String { 12 | return value 13 | } 14 | 15 | override fun decrypt(value: String): String { 16 | return value 17 | } 18 | } -------------------------------------------------------------------------------- /fileTemplates/ViewModel with ActionDispatcher.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.domain.viewmodels#end 2 | 3 | import android.app.Application 4 | import com.kortisan.content.presentation.tagging.${NAME}SceneBuilder 5 | import com.kortisan.framework.bloc.ReduxViewModelBase 6 | import com.kortisan.framework.bloc.ViewModelActionDispatcher 7 | import com.kortisan.framework.redux.stores.ApplicationStateStore 8 | import kotlinx.coroutines.flow.flow 9 | 10 | #parse("File Header.java") 11 | class ${NAME}ViewModel( 12 | application: Application, 13 | vmActionDispatcher: ViewModelActionDispatcher 14 | ): ReduxViewModelBase( application, vmActionDispatcher ) { 15 | private val taggingScene${NAME} = ${NAME}SceneBuilder.Builder() 16 | .setRootName("${NAME}") 17 | .build() 18 | } -------------------------------------------------------------------------------- /fileTemplates/ViewModel with ActionDispatcher.kt.child.0.kt: -------------------------------------------------------------------------------- 1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.presentation.tagging#end 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.SceneBuilderBase 4 | 5 | #parse("File Header.java") 6 | class ${NAME}SceneBuilder private constructor(): SceneBuilderBase() { 7 | class Builder: SceneBuilderBase.Builder() { 8 | override val taggingScene: SceneBuilderBase = ${NAME}SceneBuilder() 9 | 10 | fun setRootName( name: String ) = apply { 11 | taggingScene.baseParams["rootName"] = name 12 | } 13 | } 14 | 15 | override fun getData(): Map = baseParams 16 | } -------------------------------------------------------------------------------- /fileTemplates/includes/File Header.java: -------------------------------------------------------------------------------- 1 | /** * * * * * * * * * 2 | * Project ${PROJECT_NAME} 3 | * Created by ${USER} on ${DAY}/${MONTH_NAME_SHORT}/${YEAR}. 4 | * * * * * * * * * * **/ -------------------------------------------------------------------------------- /framework/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /framework/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias( libs.plugins.android.library ) 3 | alias( libs.plugins.android.library.kotlin ) 4 | alias( libs.plugins.android.library.protobuf ) 5 | alias( libs.plugins.android.library.kapt ) 6 | alias( libs.plugins.devtools.ksp ) 7 | alias( libs.plugins.compose.compiler ) 8 | // Habilitar cuando se instale google-services.json 9 | // id 'com.google.gms.google-services' 10 | } 11 | 12 | apply from: "$rootDir.path/projectBuildSettings/projectBuild.gradle" 13 | def config = ext.projectGradleConfig 14 | 15 | android { 16 | namespace 'com.kortisan.framework' 17 | compileSdk config.compileSdkVersion 18 | compileSdkVersion config.compileSdkVersion 19 | 20 | defaultConfig { 21 | minSdk config.minSdkVersion 22 | targetSdk config.targetSdkVersion 23 | compileSdk config.compileSdkVersion 24 | compileSdkVersion config.compileSdkVersion 25 | version getVersionName() 26 | 27 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 28 | 29 | consumerProguardFiles "consumer-rules.pro" 30 | } 31 | 32 | buildFeatures { 33 | buildConfig true 34 | } 35 | 36 | libraryVariants.all { variant -> 37 | kotlin.sourceSets { 38 | def name = variant.name 39 | getByName(name) { 40 | kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin") 41 | } 42 | } 43 | } 44 | } 45 | 46 | apply from: "$rootDir.path/projectBuildSettings/projectDependenciesFramework.gradle" 47 | apply from: "$rootDir.path/projectBuildSettings/protobufSettings.gradle" 48 | 49 | dependencies { 50 | // KSP Annotation processor 51 | implementation project(path: ':ksp') 52 | ksp project(":ksp") 53 | } -------------------------------------------------------------------------------- /framework/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/framework/consumer-rules.pro -------------------------------------------------------------------------------- /framework/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /framework/src/androidTest/java/com/kortisan/framework/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.kortisan.framework.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/FrameworkApplicationBinding.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import com.kortisan.framework.redux.actions.LoadStateAction 6 | import com.kortisan.framework.redux.controllers.navigation.strategies.NavigationStrategy 7 | import com.kortisan.framework.redux.stores.ApplicationStateStore 8 | 9 | open class FrameworkApplicationBinding: Application() { 10 | companion object { 11 | lateinit var appContext: Context 12 | } 13 | 14 | override fun onCreate() { 15 | super.onCreate() 16 | 17 | appContext = applicationContext 18 | 19 | registerActivityLifecycleCallbacks( 20 | NavigationStrategy 21 | ) 22 | 23 | // Cargamos el estado previo de la aplicación 24 | ApplicationStateStore.reduceAction( LoadStateAction ) 25 | } 26 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/BaseBloc.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import androidx.compose.runtime.Composable 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | import kotlinx.coroutines.CoroutineScope 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | 13 | 14 | /** 15 | * Clase base para que todos los BLoC extiendan 16 | * V: ViewModel donde se encuentra el Bloc o su padre 17 | * B: Tipo de dato que va a representarse en el Bloc 18 | */ 19 | abstract class BaseBloc( 20 | open val viewModelActionDispatcher: V, 21 | open val state: BlocState 22 | ) { 23 | /** 24 | * Este método debe llamarse en el init {} de los bloc DESPUÉS de declarar las variables 25 | */ 26 | fun observeActions() { 27 | CoroutineScope( Dispatchers.IO ).launch { 28 | viewModelActionDispatcher.currentAction.collect { 29 | reduce( it ) 30 | } 31 | } 32 | } 33 | 34 | fun dispatch( action: ReduxAction) = viewModelActionDispatcher.dispatch( action ) 35 | open fun reduce( action: ReduxAction ) { /* Reduce una acción en los estados del BLoC */ } 36 | 37 | @Composable 38 | abstract fun Render() 39 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/BaseUseCase.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | 5 | /** 6 | * Caso de uso base para extender a los demás 7 | * Tipo I: Valor de entrada 8 | * Tipo O: Valor de salida 9 | * Tipo T: Valor de los parámetros del caso de uso 10 | */ 11 | interface BaseUseCase { 12 | /** 13 | * Establece los parámetros para el funcionamiento del caso de uso 14 | */ 15 | fun setParams( params: P ) 16 | 17 | /** 18 | * Recibe un flujo de recursos y produce otro flujo de recursos depués de transformarlo 19 | * a partir de los parámetros definidos en la implementación del caso de uso. 20 | */ 21 | fun transformResource( inputData: Flow> ): Flow> 22 | fun transform( inputData: Flow ): Flow 23 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/BlocState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface 8 | import com.kortisan.framework.redux.stores.ApplicationStateStore 9 | import kotlinx.coroutines.flow.Flow 10 | 11 | data class BlocState ( 12 | val applicationState: ApplicationStateStore, 13 | val scene: SceneDecoratorInterface, 14 | // Los eventos deben estar en el estado del componente 15 | val componentState: Flow, 16 | ) -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/ReduxViewModelBase.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.ViewModel 5 | 6 | abstract class ReduxViewModelBase private constructor(): ViewModel() { 7 | private lateinit var _application: Application 8 | private lateinit var _vmActionDispatcher: ViewModelActionDispatcher 9 | 10 | constructor( 11 | application: Application, 12 | vmActionDispatcher: ViewModelActionDispatcher 13 | ): this() { 14 | _application = application 15 | _vmActionDispatcher = vmActionDispatcher 16 | } 17 | 18 | @Suppress("UNCHECKED_CAST") 19 | fun< T: Application> getApplication(): T = _application as T 20 | fun getDispatcher() = _vmActionDispatcher 21 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/Resource.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import java.lang.Exception 8 | 9 | sealed class Resource { 10 | data class Success(val data: T?, val message: String? = ""): Resource() 11 | data class Error(val exception: Exception, val folio: String? = "", val message: String? = ""): Resource() 12 | data class Loading(val data: Any? = null): Resource() 13 | 14 | companion object { 15 | fun success(data: T): Resource = Success(data) 16 | fun error(exception: Exception, folio: String? = "", message: String? = ""): Resource = Error(exception, folio, message) 17 | fun loading(data: Any? = null): Resource = Loading(data) 18 | } 19 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/SingleActivityWithViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | 3 | interface SingleActivityWithViewModel { 4 | val singleActivityViewModel: ReduxViewModelBase 5 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/bloc/ViewModelActionDispatcher.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.bloc 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import kotlinx.coroutines.flow.StateFlow 9 | 10 | interface ViewModelActionDispatcher { 11 | val currentAction: StateFlow 12 | fun dispatch(action: ReduxAction) 13 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entities/Address.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entities 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | data class Address( 8 | var street: String = "", 9 | var numberExt: String = "", 10 | var numberInt: String = "", 11 | var postalAddress: String = "", 12 | var neighborhood: String = "", 13 | var population: String = "", // Población aka. City 14 | var state: String = "", 15 | var country: String = "", 16 | var lat: String = "", 17 | var long: String = "", 18 | var type: String = "", 19 | var address: String = "", 20 | var colony: String = "", 21 | val shortAddress: String = "${street.replaceFirstChar { it.uppercaseChar() }} $postalAddress" 22 | ) 23 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entities/Device.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entities 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import java.util.* 8 | 9 | data class Device( 10 | var id: String = "", // Id del dispositivo 11 | var pushId: String = "", // Id de la notificación push 12 | var model: String = "", 13 | var hashInfo: String = UUID.randomUUID().toString(), 14 | var deviceName: String = "", 15 | var carrier: String = "", 16 | var idfa: String = "", 17 | val type: String = "android", 18 | var countryCode: String = "+52", // Código de país 19 | ) 20 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entities/DynamicKeys.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entities 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | data class DynamicKeys( 8 | var aesPublic : String = "", 9 | var aesPrivate : String = "", 10 | ) 11 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entities/Tokens.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entities 2 | 3 | import org.joda.time.DateTime 4 | 5 | /** * * * * * * * * * 6 | * Project KoreFrame 7 | * Created by Jacobo G Tamayo on 30/12/22. 8 | * * * * * * * * * * **/ 9 | 10 | data class Tokens( 11 | val bearer: String, 12 | val bearerAge: String, 13 | val bearerExpireTime: Int, 14 | 15 | val user: String, 16 | val userAge: String, 17 | val userExpireTime: Int, 18 | 19 | val refresh: String, 20 | val refreshAge: String, 21 | val refreshExpireTime:Int, 22 | ) { 23 | val isBearerTokenValid: Boolean 24 | get() = bearer.isNotBlank() 25 | && bearerAge.isNotBlank() 26 | && DateTime.parse( bearerAge ).isAfterNow 27 | 28 | val isAccessTokenValid: Boolean 29 | get() = user.isNotBlank() 30 | && userAge.isNotBlank() 31 | && DateTime.parse( userAge ).isAfterNow 32 | 33 | val isRefreshTokenValid: Boolean 34 | get() = refresh.isNotBlank() 35 | && refreshAge.isNotBlank() 36 | && DateTime.parse( refreshAge ).isAfterNow 37 | } 38 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/ActorProviderStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | 3 | import android.content.Intent 4 | import com.kortisan.framework.redux.actions.ReduxAction 5 | 6 | /** * * * * * * * * * 7 | * Project KoreFrame 8 | * Created by Jacobo G Tamayo on 06/01/23. 9 | * * * * * * * * * * **/ 10 | data class ActorProviderStrategy( private val intent: Intent ): EntrypointStrategy() { 11 | override fun getAction(): ReduxAction { 12 | TODO("Not yet implemented") 13 | } 14 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/ClevertapEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Intent 8 | import com.google.gson.JsonParseException 9 | import com.google.gson.JsonParser 10 | import com.google.gson.JsonSyntaxException 11 | import com.kortisan.framework.redux.actions.ReduxAction 12 | import java.lang.Exception 13 | 14 | class ClevertapEntrypointStrategy( private val intent: Intent ): EntrypointStrategy() { 15 | override fun getAction(): ReduxAction = 16 | try { 17 | val clevertapPayload = intent.getStringExtra("clevertapPayload") ?: "{}" 18 | val json = JsonParser.parseString( clevertapPayload ).asJsonObject 19 | val flowName = json["targetFlowName"]?.asString ?: "" 20 | 21 | getNavigationActionFromJson( json, flowName) 22 | }catch (e: JsonSyntaxException) { 23 | ReduxAction.EmptyAction 24 | }catch (e: JsonParseException) { 25 | ReduxAction.EmptyAction 26 | }catch (e: Exception) { 27 | ReduxAction.EmptyAction 28 | } 29 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/ComposeNavigationEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | 9 | data class ComposeNavigationEntrypointStrategy(val exampleAttributeFlowNameFromPayload: String): EntrypointStrategy() { 10 | override fun getAction(): ReduxAction = ReduxAction.EmptyAction 11 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/DeeplinkEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Intent 8 | import com.google.gson.JsonParseException 9 | import com.google.gson.JsonParser 10 | import com.google.gson.JsonSyntaxException 11 | import com.kortisan.framework.redux.actions.ReduxAction 12 | import java.lang.Exception 13 | 14 | /** 15 | * El DeepLink es nativo de Android 16 | * https://developer.android.com/training/app-links/deep-linking?hl=es-419 17 | */ 18 | data class DeeplinkEntrypointStrategy( private val intent: Intent ): EntrypointStrategy() { 19 | override fun getAction(): ReduxAction = 20 | try { 21 | val deepLinkPayload = intent.getStringExtra("deeplinkPayload") ?: "{}" 22 | val json = JsonParser.parseString(deepLinkPayload).asJsonObject 23 | val flowName: String = json["flowName"]?.asString ?: "" 24 | 25 | getNavigationActionFromJson( json, flowName ) 26 | } catch (e: JsonSyntaxException) { 27 | ReduxAction.EmptyAction 28 | } catch (e: JsonParseException) { 29 | ReduxAction.EmptyAction 30 | } catch (e: Exception) { 31 | ReduxAction.EmptyAction 32 | } 33 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/GoogleAssistantEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.NavigationActions 8 | 9 | data class GoogleAssistantEntrypointStrategy(val exampleAttributeFlowNameFromPayload: String): EntrypointStrategy() { 10 | override fun getAction(): NavigationActions { 11 | TODO("Not yet implemented") 12 | // NavigationAction.navigateToTarget( 13 | // NavigationTarget.let { 14 | // it.genericTarget( 15 | // it.flowNameAsActivityTarget.get( 16 | // exampleAttributeFlowNameFromPayload 17 | // )?.className ?: it.defaultTarget.activity.className 18 | // ) 19 | // }, 20 | // params = null 21 | // ) 22 | } 23 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/IntentEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Intent 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | 10 | data class IntentEntrypointStrategy( private val intent: Intent ): EntrypointStrategy() { 11 | /** 12 | * Lista de los entrypoints que ocupan el intent 13 | */ 14 | private val dependentEntryPoints = listOf( 15 | AppLinksEntrypointStrategy ( intent ), 16 | ClevertapEntrypointStrategy( intent ), 17 | OneLinkEntrypointStrategy ( intent ), 18 | DeeplinkEntrypointStrategy ( intent ), 19 | ) 20 | 21 | override fun getAction(): ReduxAction = dependentEntryPoints 22 | .map { it.getAction() } 23 | .firstOrNull { it !is ReduxAction.EmptyAction } 24 | ?: ReduxAction.EmptyAction 25 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/OneLinkEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Intent 8 | import com.google.gson.JsonParseException 9 | import com.google.gson.JsonParser 10 | import com.google.gson.JsonSyntaxException 11 | import com.kortisan.framework.redux.actions.ReduxAction 12 | 13 | /*** 14 | * OneLink es controlado por AppsFlyer 15 | * https://support.appsflyer.com/hc/es/articles/115005248543-Descripci%C3%B3n-general-de-OneLink 16 | */ 17 | data class OneLinkEntrypointStrategy( private val intent: Intent): EntrypointStrategy() { 18 | override fun getAction(): ReduxAction = 19 | try { 20 | val oneLinkPayload = intent.getStringExtra("onelinkPayload") ?: "{}" 21 | val json = JsonParser.parseString( oneLinkPayload ).asJsonObject 22 | val flowName = json["targetFlowName"]?.asString ?: "" 23 | 24 | getNavigationActionFromJson( json, flowName, true ) 25 | }catch (e: JsonSyntaxException) { 26 | ReduxAction.EmptyAction 27 | }catch (e: JsonParseException) { 28 | ReduxAction.EmptyAction 29 | }catch (e: java.lang.Exception) { 30 | ReduxAction.EmptyAction 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/PushNotificationEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import java.lang.Exception 9 | 10 | data class PushNotificationEntrypointStrategy( 11 | val data: Map 12 | ): EntrypointStrategy() { 13 | override fun getAction(): ReduxAction = try { 14 | val flowName = data["targetFlowName"] 15 | ?: "" 16 | 17 | if( flowName.isNotEmpty() ) 18 | getNavigationActionFromMap( data, flowName ) 19 | else 20 | data["action"] 21 | ?.let { actionName -> 22 | // Acción de redux desde el catálogo 23 | ReduxAction.getAction( actionName, data ) 24 | }?: ReduxAction.EmptyAction 25 | } catch (e: Exception) { 26 | ReduxAction.EmptyAction 27 | } 28 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/entrypoints/ShortcutEntrypointStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.entrypoints 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.NavigationActions 8 | 9 | class ShortcutEntrypointStrategy(val shortcutId: String): EntrypointStrategy() { 10 | override fun getAction(): NavigationActions { 11 | TODO("Not yet implemented") 12 | } 13 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/BiometricsActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | sealed class BiometricsActions: ReduxAction() { 4 | object AskBiometricsAction: BiometricsActions() 5 | 6 | } 7 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/DefaultErrorAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | /** 4 | * Esta acción captura la información de un error de forma predeterminada 5 | * Es procesada en el middleware de captura de errores 6 | */ 7 | data class DefaultErrorAction( 8 | val title: String, 9 | val description: String = "", 10 | val exception: Exception? = null, 11 | val extras: Map = mapOf() 12 | ): ReduxAction() 13 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/EnrollmentActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | sealed class AuthenticationActions: ReduxAction() { 8 | data class MigrateUser(val icu: String, val cellphone: String, val passcode: String): AuthenticationActions() 9 | object VerifyLiteAuthentication: AuthenticationActions() 10 | } 11 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/EventsActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import androidx.compose.ui.focus.FocusState 8 | import androidx.compose.ui.input.key.KeyEvent 9 | import androidx.compose.ui.layout.LayoutCoordinates 10 | import androidx.compose.ui.unit.IntSize 11 | 12 | sealed class EventsActions: ReduxAction() { 13 | data class OnKeyEvent ( val keyEvent: KeyEvent? ): EventsActions() 14 | data class OnSizeChanged ( val intSize: IntSize? ): EventsActions() 15 | data class OnFocusChanged ( val focusState: FocusState? ): EventsActions() 16 | data class OnFocusEventAction ( val focusState: FocusState? ): EventsActions() 17 | data class OnPreviewKeyEvent ( val onPreviewKeyEvent: KeyEvent? ): EventsActions() 18 | data class OnGloballyPositioned ( val layoutCoordinates: LayoutCoordinates? ): EventsActions() 19 | } 20 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/ExitGateAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | import com.kortisan.framework.redux.controllers.gates.BaseGate 4 | import com.kortisan.framework.redux.controllers.gates.ExitGateResult 5 | 6 | /** 7 | * Acción para salida de un subflujo con un resultado. 8 | */ 9 | data class ExitGateAction ( 10 | val result: ExitGateResult 11 | ): ReduxAction() { 12 | data class SetRawDataResultAction ( 13 | val gate: BaseGate, 14 | val originalAction: ReduxAction, 15 | val resultAction: ReduxAction, 16 | val data: T 17 | ): ReduxAction() 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/GeopositionActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | import com.kortisan.framework.redux.state.GeopositionState 4 | 5 | sealed class GeopositionActions: ReduxAction() { 6 | data class SetGeopositionAppStateAction( val newState: GeopositionState ): GeopositionActions() 7 | } 8 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/LoadStateAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | /** 4 | * Esta acción indica a los reductores de un estado que deben recuperar su información de un 5 | * CaretakerStrategy en caso de que se haya especificado. 6 | */ 7 | object LoadStateAction: ReduxAction() -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/NavigationActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 8 | 9 | sealed class NavigationActions: ReduxAction() { 10 | 11 | data class NavigateToTarget( 12 | val target: NavigationTarget 13 | ): NavigationActions() 14 | 15 | data class NavigateToTargetWithParams( 16 | val target: NavigationTarget, 17 | val params: Map 18 | ): NavigationActions() 19 | 20 | data class NavigateToClass( 21 | val className: String, 22 | val params: Map 23 | ): NavigationActions() 24 | 25 | data class NavigateToRoute( 26 | val route: String, 27 | val params: Map 28 | ): NavigationActions() 29 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/NotificationActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions /** * * * * * * * * * * Project KoreFrame * Created by Jacobo G Tamayo on 30/12/22. * * * * * * * * * * **/ import com.kortisan.framework.redux.controllers.notifications.NotificationChannel sealed class NotificationActions: ReduxAction() { data class ShowNotification( val title: String, val bodyText: String, val group: String, val autoCancel: Boolean = true, val smallIcon: Int, val urlImage: String? = null, val channel: NotificationChannel = NotificationChannel.MYAPP, // Se convierte de ReduxAction a Intent en el middleware val action: ReduxAction? = null, ): NotificationActions() data class HideNotification( val notificationId: Int ): NotificationActions() data object HideAllNotifications: NotificationActions() } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/PerformanceScoreActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | sealed class PerformanceScoreActions: ReduxAction() { 4 | object CalculateScore: PerformanceScoreActions() 5 | data class SetPerformanceScoreAction( val newScore: Int ): PerformanceScoreActions() 6 | } 7 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/ReDispatchAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | /** 4 | * Esta acción está diseñada para cuando un controlador o middleware quiere que se vuelva a 5 | * procesar una acción resultado sin que esta llegue a donde se originó la primera. 6 | * 7 | * Reinicia el ciclo del despachador. 8 | */ 9 | data class ReDispatchAction( 10 | val action: ReduxAction 11 | ): ReduxAction() -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/RemoteConfigActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | sealed class RemoteConfigActions: ReduxAction() { 8 | object ReloadAction: RemoteConfigActions() 9 | 10 | sealed class StoreRemoteConfigAction: RemoteConfigActions() { 11 | data class LoadFailAction( val exception: Exception ): StoreRemoteConfigAction() 12 | data class RefreshFailAction( val exception: Exception ): StoreRemoteConfigAction() 13 | data class SuccessLoadAction( val content: Map ): StoreRemoteConfigAction() 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/RevertAction.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | /** 8 | * Acción opcional que pueden contener algunas acciones para 9 | * poder 'deshacer' su efecto en el estado de la aplicación 10 | */ 11 | open class RevertAction: ReduxAction() -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/SensorsActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | 3 | sealed class SensorsActions: ReduxAction() { 4 | data class SetRefreshRateAction( 5 | val refreshRate: Int = 60 6 | ): SensorsActions() 7 | 8 | data class StoreSensorsAppStateAction( 9 | val linearAcc: Int, 10 | val pressureHpa: Int, 11 | val ambientLightLx: Int, 12 | val magneticFieldUt: Int, 13 | val relativeHumidity: Int, 14 | val deviceTemperatureCelsius: Int, 15 | val ambientTemperatureCelsius: Int, 16 | ): SensorsActions() 17 | } 18 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/UpdateActions.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | /** 8 | * Permiten actualizar a la aplicación bajo políticas internas y de la misma play store, 9 | * haciendo uso del middleware de actualizaciones ya que hay acciones que van a demandar 10 | * tener la última versión de la aplicación antes de poder ser consumadas. 11 | * 12 | * @see CheckUpdatePlayCoreAction 13 | * @see CheckUpdateFlagAction 14 | * @see StartUpdateAction 15 | * @see CancelUpdateAction 16 | * @see DownloadUpdateAction 17 | * @see com.kortisan.framework.redux.state.UpdateState 18 | */ 19 | sealed class UpdateActions: ReduxAction() { 20 | /** 21 | * Comprueba que hayan actualizaciones en la tienda 22 | * @see UpdateActions 23 | * @see com.kortisan.framework.redux.controllers.updatesController.UpdatesController 24 | */ 25 | data object CheckUpdatePlayCoreAction: UpdateActions() 26 | 27 | /** 28 | * Comprueba la bandera que indica que hay que actualizar forzosamente 29 | * @see UpdateActions 30 | * @see com.kortisan.framework.redux.controllers.updatesController.UpdatesController 31 | */ 32 | data object CheckUpdateFlagAction: UpdateActions() 33 | 34 | /** 35 | * Inicia el proceso de actualización (Instalación) 36 | * @see UpdateActions 37 | * @see com.kortisan.framework.redux.controllers.updatesController.UpdatesController 38 | */ 39 | data object StartUpdateAction: UpdateActions() 40 | 41 | /** 42 | * Cancela el proceso de actualización 43 | * @see UpdateActions 44 | * @see com.kortisan.framework.redux.controllers.updatesController.UpdatesController 45 | */ 46 | data object CancelUpdateAction: UpdateActions() 47 | 48 | /** 49 | * Inicia la descarga de la actualización opcional 50 | * @see UpdateActions 51 | * @see com.kortisan.framework.redux.controllers.updatesController.UpdatesController 52 | */ 53 | data object DownloadUpdateAction: UpdateActions() 54 | } 55 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/wrappers/ActionEventInstance.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions.wrappers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | 9 | data class ActionEventInstance( 10 | override val onClick: ReduxAction? = null, 11 | override val onFocus: ReduxAction? = null, 12 | override val onKeyEvent: ReduxAction? = null, 13 | override val onLongClick: ReduxAction? = null, 14 | override val onDoubleClick: ReduxAction? = null, 15 | override val onSizeChanged: ReduxAction? = null, 16 | override val onFocusChanged: ReduxAction? = null, 17 | override val onPreviewKeyEvent: ReduxAction? = null, 18 | override val onGloballyPositioned: ReduxAction? = null, 19 | override val onSwipe: ReduxAction? = null, 20 | override val onDragEnd: ReduxAction? = null, 21 | override val onScrollEnd: ReduxAction? = null, 22 | override val onDragStart: ReduxAction? = null, 23 | override val onPanChange: ReduxAction? = null, 24 | override val onZoomChange: ReduxAction? = null, 25 | override val onScrollStart: ReduxAction? = null, 26 | override val onRotationChange: ReduxAction? = null, 27 | override val onSelected: ReduxAction? = null, 28 | ): AttachedEventsInterface -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/actions/wrappers/AttachedEventsInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.actions.wrappers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | 9 | /** 10 | * Lista de modificadores que se pueden asociar a un componente 11 | * https://developer.android.com/jetpack/compose/modifiers-list?hl=es-419 12 | */ 13 | interface AttachedEventsInterface { 14 | val onClick: ReduxAction? 15 | val onFocus: ReduxAction? 16 | val onKeyEvent: ReduxAction? 17 | val onLongClick: ReduxAction? 18 | val onDoubleClick: ReduxAction? 19 | val onSizeChanged: ReduxAction? 20 | val onFocusChanged: ReduxAction? 21 | val onPreviewKeyEvent: ReduxAction? 22 | val onGloballyPositioned: ReduxAction? 23 | 24 | // TODO: Crear envoltorio para asociar estos eventos a los estados 25 | val onSwipe: ReduxAction? 26 | val onDragEnd: ReduxAction? 27 | val onScrollEnd: ReduxAction? 28 | val onDragStart: ReduxAction? 29 | val onPanChange: ReduxAction? 30 | val onZoomChange: ReduxAction? 31 | val onScrollStart: ReduxAction? 32 | val onRotationChange: ReduxAction? 33 | 34 | // TODO: Definir en el callback del un objeto seleccionable 35 | val onSelected: ReduxAction? 36 | } 37 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/ReduxControllerAbstract.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | import com.kortisan.framework.redux.stores.ApplicationStateStore 5 | import kotlinx.coroutines.flow.MutableStateFlow 6 | import kotlinx.coroutines.flow.StateFlow 7 | 8 | abstract class ReduxControllerAbstract { 9 | private val isStartedMutable: MutableStateFlow = 10 | MutableStateFlow( ReduxControllerState.Stopped ) 11 | 12 | open val isStarted: StateFlow = isStartedMutable 13 | 14 | var currentAction: ReduxAction? = null 15 | 16 | open fun start() = 17 | setStartStatus( ReduxControllerState.Started ) 18 | 19 | fun reduceApplicationState( action: ReduxAction ) = 20 | ApplicationStateStore.reduceAction( action ) 21 | 22 | fun setStartStatus( newState: ReduxControllerState ) { 23 | isStartedMutable.value = newState 24 | } 25 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/ReduxControllerState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers 2 | 3 | import com.kortisan.framework.redux.state.ReduxState 4 | 5 | sealed class ReduxControllerState: ReduxState() { 6 | object Stopped: ReduxControllerState() 7 | object Starting: ReduxControllerState() 8 | object Started: ReduxControllerState() 9 | data class ErrorOnStart( 10 | val errorMessage: String, 11 | val exception: Exception? = null 12 | ): ReduxControllerState() 13 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/gates/ExitGateResult.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.gates 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | 9 | /** 10 | * Acción para salida de un subflujo con un resultado 11 | * 12 | * Puede tener una acción resultado que reemplazará a la acción original, es necesario en 13 | * caso de que una flujo que haya invocado un subflujo requiera reducir un estado a partir 14 | * de una acción resultado del subflujo. 15 | * 16 | * Esto puede implicar que los gates tengan su catálogo de acciones resultado para que los 17 | * flujos puedan reducir estos valores. 18 | * 19 | * Adicionalmente pueden producir valores crudos para otras operaciones. 20 | */ 21 | sealed interface ExitGateResult { 22 | val rawDataResult: T? 23 | data class Success( 24 | val customResultSuccessAction: ReduxAction? = null, 25 | override val rawDataResult: T? = null 26 | ): ExitGateResult 27 | data class Fail ( 28 | val customResultFailAction: ReduxAction? = null, 29 | override val rawDataResult: T? = null 30 | ): ExitGateResult 31 | data class Retry ( 32 | val customResultRetryAction: ReduxAction? = null, 33 | override val rawDataResult: T? = null 34 | ): ExitGateResult 35 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/geoposition/GeopositionController.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.geoposition 2 | 3 | import com.kortisan.framework.redux.actions.GeopositionActions 4 | import com.kortisan.framework.redux.controllers.ReduxControllerAbstract 5 | import com.kortisan.framework.redux.controllers.ReduxControllerState 6 | import com.kortisan.framework.redux.state.GeopositionState 7 | 8 | class GeopositionController: ReduxControllerAbstract() { 9 | override fun start() { 10 | // Comprobamos los permisos de ubicación 11 | setStartStatus( ReduxControllerState.Starting ) 12 | reduceApplicationState( 13 | GeopositionActions.SetGeopositionAppStateAction( GeopositionState.Loading ) 14 | ) 15 | TODO("Obtener posición del GPS y modificar el estado de la aplicación") 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/FlowNameAlias.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | data class FlowNameAlias( 8 | val alias: String, 9 | val disabled: Boolean = false 10 | ) 11 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/PrimitiveTargetActivityIdentifier.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | data class PrimitiveTargetActivityIdentifier( 8 | val className: String, 9 | val flowName: String = "", 10 | val section: String = "", 11 | val flowNameAlias: FlowNameAlias? = null 12 | ) 13 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/contracts/CustomActivityContract.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.contracts 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.app.Activity 8 | import android.content.Context 9 | import android.content.Intent 10 | import androidx.activity.result.contract.ActivityResultContract 11 | import com.kortisan.framework.toBundle 12 | import com.kortisan.framework.toMap 13 | 14 | /** 15 | * Contrato para registrar la respuesta de una actividad y pasar estos parámetros a otra actividad 16 | * que será la que haga la llamada. 17 | */ 18 | class CustomActivityContract( 19 | // Activity 20 | private val activityCannonicalName: String 21 | ): ActivityResultContract, ResultContractStatus>() { 22 | override fun createIntent( context: Context, input: Map ): Intent = 23 | Intent() 24 | .setClassName( context, activityCannonicalName ) 25 | .putExtras( input.toBundle() ) 26 | 27 | override fun parseResult( resultCode: Int, intent: Intent? ): ResultContractStatus = 28 | resultCode.let { 29 | val intentExtras = intent?.extras?.toMap() ?: mapOf() 30 | 31 | when( it ) { 32 | Activity.RESULT_OK -> ResultContractStatus.Success( it, intentExtras ) 33 | Activity.RESULT_CANCELED -> ResultContractStatus.Error( it ) 34 | else -> ResultContractStatus.CustomStatus( it, intentExtras ) 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/contracts/ReduxActivityResultContract.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.contracts 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.os.Bundle 7 | import androidx.activity.result.contract.ActivityResultContract 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | import com.kortisan.framework.redux.controllers.gates.ExitGateResult 10 | import com.kortisan.framework.toBundle 11 | import com.kortisan.framework.toMap 12 | 13 | class ReduxActivityResultContract( 14 | private val activityClassName: String 15 | ): ActivityResultContract, ExitGateResult>() { 16 | override fun createIntent( context: Context, input: Map ): Intent = 17 | Intent() 18 | .setClassName( context, activityClassName ) 19 | .putExtras( input.toBundle() ) 20 | 21 | /** 22 | * Convierte el resultado del activity lanzado en una acción Redux 23 | */ 24 | override fun parseResult(resultCode: Int, intent: Intent?): ExitGateResult = 25 | resultCode.let { 26 | val intentExtras = intent?.extras?.toMap() ?: mapOf() 27 | 28 | val resultAction: ReduxAction? = intentExtras["action"]?.let { actionName -> 29 | ReduxAction.getAction( actionName, intentExtras ) 30 | } 31 | 32 | when( it ) { 33 | Activity.RESULT_OK -> ExitGateResult.Success( resultAction, intent?.extras ) 34 | //Activity.RESULT_CANCELED -> ExitGateResult.Fail( resultAction, intent?.extras ) 35 | else -> ExitGateResult.Fail( resultAction, intent?.extras ) 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/contracts/ResultContractStatus.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.contracts 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | sealed class ResultContractStatus { 8 | data class Success( 9 | val resultCode: Int, 10 | val resultData: Map 11 | ): ResultContractStatus() 12 | 13 | data class Error( 14 | val errorCode: Int 15 | ): ResultContractStatus() 16 | 17 | data class CustomStatus( 18 | val resultCode: Int, 19 | val resultData: Map 20 | ): ResultContractStatus() 21 | } 22 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/protocol/DefaultParams.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.protocol 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | @Retention(AnnotationRetention.RUNTIME) 8 | annotation class DefaultParams(val json: String) 9 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/protocol/NavigationTarget.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.protocol 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.RevertAction 8 | import com.kortisan.framework.redux.controllers.gates.BaseGate 9 | import java.util.* 10 | 11 | /** 12 | * Esta clase define todas las rutas posibles disponible dentro de la aplicación 13 | * Los métodos disponibles para crear las instancias sirven para documentar los parámetros 14 | * requeridos por cada una de las vistas. 15 | * Así también existe una ruta genérica para las rutas no disponibles. 16 | */ 17 | open class NavigationTarget { 18 | val actionTargetSack: Stack = Stack() 19 | 20 | open val accessGate: BaseGate? = null 21 | } 22 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/protocol/StartComposeDestination.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.protocol 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | /** 8 | * Define una ruta TargetCompose como primaria para el controlador de rutas 9 | * Si hay más de una anotación dentro de un TargetActivity se usará la primera como predeterminada 10 | */ 11 | @Retention( AnnotationRetention.RUNTIME ) 12 | annotation class StartComposeDestination 13 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/AuthenticationNavigationGroup.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | 3 | import com.kortisan.framework.redux.controllers.navigation.PrimitiveTargetActivityIdentifier 4 | 5 | class AuthenticationNavigationGroup (override val prefixPath: String = "Authentication"): 6 | NavigationTargetGroup { 7 | object Authentication: TargetActivity("/", AuthenticationActivityTarget.target ) { 8 | object LoginCompose: TargetCompose( 9 | Authentication, "/login") 10 | 11 | object ReadBiometricsCompose: TargetCompose( 12 | Authentication, "/read_biometrics") 13 | 14 | object ConfirmPasswordCompose: TargetCompose( 15 | Authentication, "/confirm_password") 16 | 17 | object AskForPasswordCompose: TargetCompose( 18 | Authentication, "/ask_for_password") 19 | 20 | object AskForEmailCompose: TargetCompose( 21 | Authentication, "/ask_for_email") 22 | 23 | } 24 | 25 | object AuthenticationActivityTarget: SealedActivityClassList( 26 | PrimitiveTargetActivityIdentifier( 27 | "com.kortisan.authentication.presentation.AuthenticationMainActivity", 28 | flowName = "AuthenticationMainActivityFlowName", 29 | section = "" ) 30 | ) 31 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/DashboardNavigationGroup.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.PrimitiveTargetActivityIdentifier 8 | import com.kortisan.framework.redux.gates.FingerprintGate 9 | 10 | class DashboardNavigationGroup(override val prefixPath: String = "dashboard"): 11 | NavigationTargetGroup { 12 | object Dashboard: TargetActivity( 13 | "/main", DashboardActivityTarget.target ) { 14 | object DashboardCompose: TargetCompose(Dashboard, "/") 15 | 16 | // override val accessGate = FingerprintGate 17 | } 18 | 19 | object ShowError: TargetActivity("/errorMessage", ShowErrorActivityTarget.target) 20 | object AskBiometrics: TargetActivity("/biometrics", AskBiometricsActivityTarget.target) 21 | 22 | object DashboardActivityTarget: SealedActivityClassList( 23 | PrimitiveTargetActivityIdentifier( 24 | "com.kortisan.content.presentation.MainActivity", 25 | flowName = "MainActivityFlowName") 26 | ) 27 | 28 | object ShowErrorActivityTarget: SealedActivityClassList( 29 | PrimitiveTargetActivityIdentifier( 30 | "com.kortisan.framework.redux.controllers.errorHandler.ShowErrorActivity", 31 | flowName = "MainActivityFlowName") 32 | ) 33 | 34 | object AskBiometricsActivityTarget: SealedActivityClassList( 35 | PrimitiveTargetActivityIdentifier( 36 | "com.kortisan.framework.redux.controllers.securityAssets.BiometricPromptActivity", 37 | "AskBiometricsFlowName" 38 | ) 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/NavigationTargetGroup.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | sealed interface NavigationTargetGroup { 8 | val prefixPath: String 9 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/NavigationTargetParams.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 8 | 9 | sealed class NavigationTargetParams(val path: String = "") 10 | // sealed class NavigationTargetParams(val targetActivity: T, val path: String = "") 11 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/SealedActivityClassList.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.PrimitiveTargetActivityIdentifier 8 | 9 | // Contenedor para el catálogo de todas las actividades de la aplicación 10 | sealed class SealedActivityClassList(val target: PrimitiveTargetActivityIdentifier) 11 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/TargetActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.PrimitiveTargetActivityIdentifier 8 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 9 | 10 | sealed class TargetActivity( 11 | val path: String, 12 | val primitiveTargetActivityIdentifier: PrimitiveTargetActivityIdentifier, 13 | ): NavigationTarget() 14 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/TargetClass.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 8 | 9 | sealed class TargetClass( 10 | val classInPackage: String, 11 | val method: String, 12 | val flowName: String, 13 | ): NavigationTarget() 14 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/TargetCompose.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 8 | 9 | sealed class TargetCompose( 10 | val targetActivity: OWNER, 11 | val path: String, 12 | ): NavigationTarget() 13 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/navigation/targets/TargetExternal.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.navigation.targets 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.net.Uri 8 | import com.kortisan.framework.redux.controllers.navigation.protocol.NavigationTarget 9 | 10 | sealed class TargetExternal ( 11 | val action: String, 12 | val uri: Uri?, 13 | val path: String? = null, 14 | val flowName: String? = null, 15 | ): NavigationTarget() 16 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/notifications/FirebaseMessagingDecorator.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.notifications import com.kortisan.framework.redux.controllers.tagging.decorators.SceneBaseDecorator import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface class FirebaseMessagingDecorator( override val sceneDecorator: SceneDecoratorInterface ): SceneBaseDecorator() { fun setPushId(pushId: String): FirebaseMessagingDecorator = apply { decoratedValues["id_push"] = pushId } fun setElement(element: String): FirebaseMessagingDecorator = apply { decoratedValues["element"] = element } fun setType(type: String): FirebaseMessagingDecorator = apply { decoratedValues["type"] = type } fun setFlowName(flowName: String): FirebaseMessagingDecorator = apply { decoratedValues["flowName"] = flowName } } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/notifications/NotificationChannel.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.notifications 2 | 3 | import android.app.NotificationManager 4 | 5 | enum class NotificationChannel(val cId: String, val cName: String, val cPriority: Int ) { 6 | MYAPP( 7 | "CHANNEL_ID_MYAPP", 8 | "InfoMyApp", 9 | NotificationManager.IMPORTANCE_DEFAULT ), 10 | 11 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/performanceScrore/CalculatePerformanceController.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.performanceScrore 2 | 3 | import com.kortisan.framework.redux.actions.PerformanceScoreActions 4 | import com.kortisan.framework.redux.controllers.ReduxControllerAbstract 5 | import kotlin.random.Random 6 | 7 | class CalculatePerformanceController: ReduxControllerAbstract() { 8 | fun calculateScore() { 9 | reduceApplicationState( 10 | PerformanceScoreActions.SetPerformanceScoreAction( 11 | Random.nextInt(0, 100) 12 | ) 13 | ) 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/remoteConfig/parsers/FlowNameAliasRemoteConfig.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.remoteConfig.parsers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | data class FlowNameAliasRemoteConfig( 8 | val available: List = listOf(), 9 | val blocked: List = listOf() 10 | ) { 11 | data class FlowAlias( 12 | val flowName: String = "", 13 | val alias: String = "", 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/remoteConfig/parsers/RemoteConfigDirectoryMap.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.remoteConfig.parsers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import kotlin.reflect.KClass 8 | 9 | object RemoteConfigDirectoryMap { 10 | val parserMap: Map> = mapOf( 11 | "flowNameAlias" to FlowNameAliasRemoteConfig::class, 12 | "taggingSettings" to TaggingSettingsRemoteConfig::class, 13 | ) 14 | 15 | var defaultAsyncMap: Map = mapOf( 16 | "byte" to ByteArray(0), 17 | "Boolean" to false, 18 | "Double" to "0".toDouble(), 19 | "Long" to 0L, 20 | "String" to "{}" 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/sensors/SensorsController.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.sensors 2 | 3 | import com.kortisan.framework.redux.controllers.ReduxControllerAbstract 4 | 5 | class SensorsController: ReduxControllerAbstract() { 6 | private var refreshRate: Int = 60 7 | override fun start() { 8 | super.start() 9 | } 10 | 11 | fun setRefreshRate( refreshRate: Int = 60 ) { 12 | this.refreshRate = refreshRate 13 | } 14 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/SceneBuilderBase.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface 4 | 5 | /** * * * * * * * * * 6 | * Project KoreFrame 7 | * Created by Jacobo G Tamayo on 01/01/23. 8 | * * * * * * * * * * **/ 9 | open class SceneBuilderBase: SceneDecoratorInterface { 10 | val baseParams: MutableMap = mutableMapOf() 11 | 12 | abstract class Builder { 13 | abstract val taggingScene: SceneBuilderBase 14 | 15 | fun build(): SceneBuilderBase = taggingScene 16 | } 17 | 18 | override fun getData(): Map = baseParams 19 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/builders/EntryPointSceneBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.builders 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.SceneBuilderBase 4 | 5 | /** * * * * * * * * * 6 | * Project KoreFrame 7 | * Created by Jacobo G Tamayo on 02/01/23. 8 | * * * * * * * * * * **/ 9 | class EntryPointSceneBuilder private constructor(): SceneBuilderBase() { 10 | class Builder private constructor (): SceneBuilderBase.Builder() { 11 | 12 | override val taggingScene: SceneBuilderBase = EntryPointSceneBuilder() 13 | 14 | init { 15 | taggingScene.baseParams.putAll( 16 | mapOf( 17 | "moduleName" to "", 18 | "flowName" to "", 19 | "eventName" to "", 20 | "origin" to "", 21 | ) 22 | ) 23 | } 24 | 25 | constructor ( moduleName: String ): this() { 26 | setModuleName( moduleName ) 27 | } 28 | 29 | fun setModuleName( moduleName: String ) = apply { 30 | taggingScene.baseParams["moduleName"] = moduleName 31 | } 32 | 33 | fun setFlowName( flowName: String ) = apply { 34 | taggingScene.baseParams["flowName"] = flowName 35 | } 36 | 37 | fun setEvent( event: String ) = apply { 38 | taggingScene.baseParams["eventName"] = event 39 | } 40 | 41 | fun setOrigin( origin: String ) = apply { 42 | taggingScene.baseParams["origin"] = origin 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/decorators/AttachEventDecorator.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.decorators 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | class AttachEventDecorator( 8 | override val sceneDecorator: SceneDecoratorInterface, 9 | val type: String = "" 10 | ): SceneBaseDecorator() { 11 | init { 12 | decoratedValues["type"] = type 13 | } 14 | 15 | fun setType( type: String ) = 16 | apply { decoratedValues["type"] = type } 17 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/decorators/SceneBaseDecorator.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.decorators 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | abstract class SceneBaseDecorator: SceneDecoratorInterface { 8 | abstract val sceneDecorator: SceneDecoratorInterface 9 | val decoratedValues: MutableMap = mutableMapOf() 10 | final override fun getData(): Map = sceneDecorator.getData() + decoratedValues 11 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/decorators/SceneDecoratorInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.decorators 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | fun interface SceneDecoratorInterface { 8 | fun getData(): Map 9 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/decorators/application/SensorsTaggingDecorator.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.decorators.application 2 | 3 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneBaseDecorator 4 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface 5 | import com.kortisan.framework.redux.state.SensorsState 6 | 7 | /** 8 | * Este decorador de taggeo agrega la información de los sensores del dispositivo 9 | * cuando esten disponibles. 10 | */ 11 | class SensorsTaggingDecorator( 12 | override val sceneDecorator: SceneDecoratorInterface, 13 | ): SceneBaseDecorator() { 14 | fun setSensorsState ( state: SensorsState ): SensorsTaggingDecorator = 15 | apply { 16 | if( state is SensorsState.DataAcquired ) { 17 | decoratedValues["sensorRefreshRateSeconds"] = 18 | "${state.refreshRateSeconds}" 19 | 20 | decoratedValues["sensorLinearAcc"] = 21 | "${state.linearAcc}" 22 | 23 | decoratedValues["sensorPressureHpa"] = 24 | "${state.pressureHpa}" 25 | 26 | decoratedValues["sensorAmbientLightLx"] = 27 | "${state.ambientLightLx}" 28 | 29 | decoratedValues["sensorMagneticFieldUt"] = 30 | "${state.magneticFieldUt}" 31 | 32 | decoratedValues["sensorRelativeHumidity"] = 33 | "${state.relativeHumidity}" 34 | 35 | decoratedValues["sensorDeviceTemperatureCelsius"] = 36 | "${state.deviceTemperatureCelsius}" 37 | 38 | decoratedValues["sensorAmbientTemperatureCelsius"] = 39 | "${state.ambientTemperatureCelsius}" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/tagging/providers/TaggingStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.tagging.providers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.controllers.tagging.decorators.SceneDecoratorInterface 8 | import com.kortisan.framework.redux.controllers.remoteConfig.parsers.TaggingSettingsRemoteConfig 9 | 10 | sealed interface TaggingStrategy { 11 | /** 12 | * Envía la información al proveedor de etiquetado 13 | */ 14 | fun sendData( 15 | scene: SceneDecoratorInterface, 16 | config: TaggingSettingsRemoteConfig.TaggingEventConfig 17 | ) 18 | 19 | /** 20 | * Inicializa al proveedor de etiquetado 21 | */ 22 | fun initialize() 23 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/controllers/updatesController/UpdatesController.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.controllers.updatesController 2 | 3 | import com.kortisan.framework.redux.controllers.ReduxControllerAbstract 4 | 5 | class UpdatesController: ReduxControllerAbstract() { 6 | fun cancelUpdate() { 7 | // applicationState.updateState.value = UpdateState.DownloadCancelled 8 | } 9 | 10 | fun checkForUpdatesOnFirebase() { // Comprobamos firebase 11 | // applicationState.updateState.value = UpdateState.CheckingUpdate 12 | } 13 | 14 | fun checkForUpdatesOnPlayCore() { // Comprobamos playcore 15 | // applicationState.updateState.value = UpdateState.CheckingUpdate 16 | } 17 | 18 | fun startDownload() { 19 | // applicationState.updateState.value = UpdateState.DownloadInProcess 20 | } 21 | 22 | fun startUpdateInstall() { 23 | // applicationState.updateState.value = UpdateState.Installing 24 | } 25 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/gates/AskForEmailGate.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.gates 2 | 3 | import com.kortisan.framework.redux.actions.DefaultErrorAction 4 | import com.kortisan.framework.redux.actions.NavigationActions 5 | import com.kortisan.framework.redux.actions.ReduxAction 6 | import com.kortisan.framework.redux.controllers.gates.BaseGate 7 | import com.kortisan.framework.redux.controllers.navigation.targets.AuthenticationNavigationGroup 8 | 9 | object AskForEmailGate: BaseGate() { 10 | override val startAction: ReduxAction = 11 | NavigationActions.NavigateToTarget( 12 | AuthenticationNavigationGroup.Authentication.AskForEmailCompose 13 | ) 14 | 15 | override val onFailAction: ReduxAction = 16 | DefaultErrorAction("Error al solicitar el Email") 17 | 18 | override fun enterInGate(startAction: ReduxAction): Boolean { 19 | return true 20 | } 21 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/gates/CheckUpdateGate.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.gates 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | import com.kortisan.framework.redux.controllers.gates.BaseGate 5 | 6 | /** * * * * * * * * * 7 | * Project KoreFrame 8 | * Created by Jacobo G Tamayo on 30/12/22. 9 | * * * * * * * * * * **/ 10 | 11 | object CheckUpdateGate: BaseGate() { 12 | override val startAction: ReduxAction 13 | get() = TODO("Not yet implemented") 14 | override val onFailAction: ReduxAction 15 | get() = TODO("Not yet implemented") 16 | 17 | override fun enterInGate(startAction: ReduxAction): Boolean { 18 | return false 19 | } 20 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/gates/FingerprintGate.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.gates 2 | 3 | import com.kortisan.framework.redux.actions.BiometricsActions 4 | import com.kortisan.framework.redux.actions.DefaultErrorAction 5 | import com.kortisan.framework.redux.actions.ReduxAction 6 | import com.kortisan.framework.redux.controllers.gates.BaseGate 7 | 8 | object FingerprintGate: BaseGate() { 9 | override val startAction: ReduxAction = 10 | BiometricsActions.AskBiometricsAction 11 | 12 | override val onFailAction: ReduxAction 13 | get() = DefaultErrorAction("No se puede solicitar la autenticación") 14 | 15 | override fun enterInGate(startAction: ReduxAction): Boolean { 16 | return true 17 | } 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/gates/LoggedGate.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.gates 2 | 3 | import com.kortisan.framework.R 4 | import com.kortisan.framework.redux.actions.NavigationActions 5 | import com.kortisan.framework.redux.actions.NotificationActions 6 | import com.kortisan.framework.redux.actions.ReduxAction 7 | import com.kortisan.framework.redux.controllers.gates.BaseGate 8 | import com.kortisan.framework.redux.controllers.navigation.targets.AuthenticationNavigationGroup 9 | import com.kortisan.framework.redux.state.SessionState 10 | import com.kortisan.framework.redux.stores.ApplicationStateStore 11 | import kotlinx.coroutines.flow.first 12 | import kotlinx.coroutines.runBlocking 13 | 14 | /** * * * * * * * * * 15 | * Project KoreFrame 16 | * Created by Jacobo G Tamayo on 30/12/22. 17 | * * * * * * * * * * **/ 18 | 19 | /** 20 | * Puerta para comprobar que el usuario haya iniciado sesión 21 | */ 22 | object LoggedGate: BaseGate() { 23 | override val startAction: ReduxAction = 24 | NavigationActions.NavigateToTarget( 25 | AuthenticationNavigationGroup.Authentication.LoginCompose 26 | ) 27 | 28 | override val onFailAction: ReduxAction = 29 | NotificationActions.ShowNotification( 30 | "Error en LoggedGate", 31 | "No se puede continuar con el login", 32 | "APP", 33 | smallIcon = R.drawable.error_24 34 | ) 35 | 36 | override val subGates: List = listOf( 37 | // AskForEmailGate 38 | ) 39 | 40 | override fun enterInGate(startAction: ReduxAction): Boolean { 41 | return runBlocking { 42 | return@runBlocking ( 43 | ApplicationStateStore.sessionState.first() is SessionState.LoggedOut 44 | ) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/gates/PasswordAuthorizationGate.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.gates 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | /** 8 | * Puerta para solicitar la contraseña si es que no se encuentra en el tiempo de gracia 9 | * desde la última solicitud o si es obligatorio solicitarla 10 | */ 11 | /* 12 | object PasswordAuthorizationGate: NavigationGate() { 13 | override val subGates: List = listOf() 14 | 15 | override val redirectTargetStart: NavigationTarget 16 | get() = TODO("Not yet implemented") 17 | 18 | override fun condition( 19 | navigationTarget: NavigationTarget, 20 | applicationState: ApplicationState 21 | ): Boolean { 22 | return super.condition(navigationTarget, applicationState) 23 | } 24 | }*/ 25 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/BiometricsMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | 3 | import com.kortisan.framework.redux.actions.BiometricsActions 4 | import com.kortisan.framework.redux.actions.ReduxAction 5 | import com.kortisan.framework.redux.controllers.ControllersProxy 6 | import com.kortisan.framework.redux.controllers.securityAssets.SecurityAssetsController 7 | import com.kortisan.framework.redux.stores.ApplicationStateStore 8 | 9 | object BiometricsMiddleware: MiddlewareInterface { 10 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { 11 | if( action is BiometricsActions ) { 12 | val controller = ControllersProxy.getController() 13 | 14 | when( action ) { 15 | BiometricsActions.AskBiometricsAction -> controller?.askForBiometrics() 16 | } 17 | } 18 | return action 19 | } 20 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/CalculatePerformanceScoreMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.PerformanceScoreActions 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | import com.kortisan.framework.redux.controllers.performanceScrore.CalculatePerformanceController 10 | import com.kortisan.framework.redux.controllers.ControllersProxy 11 | import com.kortisan.framework.redux.stores.ApplicationStateStore 12 | 13 | /** 14 | * Este Middleware calcula la puntuación del teléfono para saber que tanto comprimir 15 | * las imágenes y los recursos. 16 | */ 17 | object CalculatePerformanceScoreMiddleware: MiddlewareInterface { 18 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction = 19 | if( action is PerformanceScoreActions.CalculateScore ) { 20 | ControllersProxy.getController() 21 | ?.calculateScore() 22 | 23 | ReduxAction.EmptyAction 24 | }else 25 | action 26 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/ErrorHandlerMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | 3 | import com.kortisan.framework.redux.actions.DefaultErrorAction 4 | import com.kortisan.framework.redux.actions.NavigationActions 5 | import com.kortisan.framework.redux.actions.ReDispatchAction 6 | import com.kortisan.framework.redux.actions.ReduxAction 7 | import com.kortisan.framework.redux.controllers.navigation.targets.DashboardNavigationGroup 8 | import com.kortisan.framework.redux.stores.ApplicationStateStore 9 | 10 | object ErrorHandlerMiddleware: MiddlewareInterface { 11 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction = 12 | if( action is DefaultErrorAction ) { 13 | ReDispatchAction( 14 | NavigationActions.NavigateToTargetWithParams( 15 | DashboardNavigationGroup.ShowError, 16 | mapOf( 17 | "title" to action.title, 18 | "description" to action.description, 19 | "exceptionName" to "${action.exception?.javaClass?.simpleName}", 20 | "exceptionMessage" to "${action.exception?.localizedMessage}", 21 | ).plus( action.extras ) 22 | ) 23 | ) 24 | } else 25 | action 26 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/MiddlewareInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import com.kortisan.framework.redux.stores.ApplicationStateStore 9 | 10 | fun interface MiddlewareInterface { 11 | fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction 12 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/NotificationMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware /** * * * * * * * * * * Project KoreFrame * Created by Jacobo G Tamayo on 30/12/22. * * * * * * * * * * **/ import com.kortisan.framework.redux.actions.NotificationActions import com.kortisan.framework.redux.actions.ReduxAction import com.kortisan.framework.redux.controllers.ControllersProxy import com.kortisan.framework.redux.controllers.notifications.PushNotificationController import com.kortisan.framework.redux.stores.ApplicationStateStore /** * Esta clase se encarga de crear las notificaciones push en la aplicación */ object NotificationMiddleware: MiddlewareInterface { override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { if (action is NotificationActions) { val notificationController = ControllersProxy.getController() when (action) { is NotificationActions.ShowNotification -> notificationController?.showNotification(action) NotificationActions.HideAllNotifications -> notificationController?.hideAllNotifications() is NotificationActions.HideNotification -> notificationController?.hideNotificationById( action.notificationId ) } } return action } } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/PositionMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.GeopositionActions 8 | import com.kortisan.framework.redux.actions.ReduxAction 9 | import com.kortisan.framework.redux.controllers.ControllersProxy 10 | import com.kortisan.framework.redux.controllers.geoposition.GeopositionController 11 | import com.kortisan.framework.redux.stores.ApplicationStateStore 12 | 13 | object PositionMiddleware: MiddlewareInterface { 14 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { 15 | if (action is GeopositionActions) 16 | ControllersProxy.getController()?.also { geoController -> 17 | // TODO: Logica para controlar el GPS 18 | when (action) { 19 | is GeopositionActions.SetGeopositionAppStateAction -> { 20 | geoController.reduceApplicationState( action ) 21 | 22 | return ReduxAction.EmptyAction 23 | } 24 | } 25 | } 26 | 27 | return action 28 | } 29 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/RemoteConfigMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import com.kortisan.framework.redux.actions.RemoteConfigActions 9 | import com.kortisan.framework.redux.controllers.ControllersProxy 10 | import com.kortisan.framework.redux.stores.ApplicationStateStore 11 | import com.kortisan.framework.redux.controllers.remoteConfig.RemoteConfigController 12 | object RemoteConfigMiddleware: MiddlewareInterface { 13 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { 14 | if ( action is RemoteConfigActions.ReloadAction ) 15 | ControllersProxy.getController()?.reloadRemoteConfig() 16 | 17 | return action 18 | } 19 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/SensorsMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | import com.kortisan.framework.redux.actions.SensorsActions 5 | import com.kortisan.framework.redux.controllers.ControllersProxy 6 | import com.kortisan.framework.redux.controllers.sensors.SensorsController 7 | import com.kortisan.framework.redux.stores.ApplicationStateStore 8 | 9 | object SensorsMiddleware: MiddlewareInterface { 10 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { 11 | if( action is SensorsActions.SetRefreshRateAction ) 12 | ControllersProxy.getController() 13 | ?.setRefreshRate( action.refreshRate ) 14 | 15 | return action 16 | } 17 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/TaggingMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import com.kortisan.framework.redux.controllers.ControllersProxy 9 | import com.kortisan.framework.redux.stores.ApplicationStateStore 10 | import com.kortisan.framework.redux.controllers.tagging.TaggingController 11 | 12 | object TaggingMiddleware: MiddlewareInterface { 13 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction { 14 | ControllersProxy.getController() 15 | ?.launchTagging( action ) 16 | 17 | return action 18 | } 19 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/middleware/UpdatesMiddleware.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.middleware 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.redux.actions.ReduxAction 8 | import com.kortisan.framework.redux.actions.UpdateActions 9 | import com.kortisan.framework.redux.controllers.ControllersProxy 10 | import com.kortisan.framework.redux.controllers.updatesController.UpdatesController 11 | import com.kortisan.framework.redux.stores.ApplicationStateStore 12 | 13 | /** 14 | * Gestiona la actualización de la aplicación mediante el Controlador de actualizaciones 15 | */ 16 | object UpdatesMiddleware: MiddlewareInterface { 17 | override fun doNext(action: ReduxAction, applicationState: ApplicationStateStore): ReduxAction = 18 | if( action is UpdateActions) { 19 | val controller = ControllersProxy.getController() 20 | 21 | when( action ) { 22 | UpdateActions.CancelUpdateAction -> 23 | controller?.cancelUpdate() 24 | 25 | UpdateActions.CheckUpdateFlagAction -> 26 | controller?.checkForUpdatesOnFirebase() 27 | 28 | UpdateActions.CheckUpdatePlayCoreAction -> 29 | controller?.checkForUpdatesOnPlayCore() 30 | 31 | UpdateActions.DownloadUpdateAction -> 32 | controller?.startDownload() 33 | 34 | UpdateActions.StartUpdateAction -> 35 | controller?.startUpdateInstall() 36 | } 37 | 38 | ReduxAction.EmptyAction 39 | } else 40 | action 41 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/ConnectivityState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | sealed class ConnectivityState: ReduxState() { 4 | object NoInternet: ConnectivityState() 5 | object ConnectedNoInternet: ConnectivityState() 6 | object OnlineNoService: ConnectivityState() 7 | object Online: ConnectivityState() 8 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/DeviceState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.kortisan.framework.entities.Device 4 | 5 | sealed class DeviceState: ReduxState() { 6 | object Loading: DeviceState() 7 | data class Initialized( 8 | val device: Device 9 | ): DeviceState() 10 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/GeopositionState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 4 | 5 | sealed class GeopositionState: ReduxState() { 6 | data class PositionAdquired( 7 | val lat: Long, 8 | val lon: Long, 9 | val alt: Long, 10 | val precision: Long = 1L 11 | ): GeopositionState() { 12 | override val productionRules: List = commonProductionRules 13 | } 14 | object Loading: GeopositionState() { 15 | override val productionRules: List = commonProductionRules 16 | } 17 | object NoPermission: GeopositionState() { 18 | override val productionRules: List = commonProductionRules 19 | } 20 | 21 | protected val commonProductionRules = listOf( 22 | // TODO: Definir reglas de producción para los estados de la ubicación 23 | ) 24 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/PerformanceScoreState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.kortisan.framework.redux.actions.PerformanceScoreActions 4 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 5 | 6 | sealed class PerformanceScoreState: ReduxState() { 7 | data class Calculated( val score: Int ): PerformanceScoreState(){ 8 | override val productionRules: List = 9 | listOf { state, action -> 10 | when ( action ) { 11 | is PerformanceScoreActions.SetPerformanceScoreAction -> 12 | Calculated( action.newScore ) 13 | else -> state 14 | } 15 | } 16 | } 17 | 18 | object NotCalculated: PerformanceScoreState() { 19 | override val productionRules: List = 20 | listOf { state, action -> 21 | when ( action ) { 22 | is PerformanceScoreActions.SetPerformanceScoreAction -> 23 | Calculated( action.newScore ) 24 | else -> state 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/PermissionState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.karumi.dexter.DexterBuilder 4 | 5 | sealed class PermissionState: ReduxState() { 6 | data class AllGranted( 7 | val permissions: List 8 | ): PermissionState() 9 | object NoPermission: PermissionState() 10 | 11 | data class PermissionNeeded( 12 | val granted: List, 13 | val notGranted: List 14 | ): PermissionState() 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/RouteFlowNamesAliasState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | sealed class RouteFlowNamesAliasState: ReduxState() { 4 | data class AliasMap( 5 | val flowNameAliasMap: Map = mapOf() 6 | ): RouteFlowNamesAliasState() 7 | object Loading: RouteFlowNamesAliasState() 8 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/SensorsState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 4 | 5 | /** 6 | * Contiene la información relacionada con los sensores de hardware 7 | */ 8 | sealed class SensorsState: ReduxState() { 9 | data object Loading: SensorsState() { 10 | override val productionRules: List = commonProductionRules 11 | } 12 | 13 | data class DataAcquired( 14 | val refreshRateSeconds: Int = 60, 15 | val linearAcc: Int, 16 | val pressureHpa: Int, 17 | val ambientLightLx: Int, 18 | val magneticFieldUt: Int, 19 | val relativeHumidity: Int, 20 | val deviceTemperatureCelsius: Int, 21 | val ambientTemperatureCelsius: Int, 22 | ): SensorsState() { 23 | override val productionRules: List = commonProductionRules 24 | } 25 | 26 | protected val commonProductionRules: List = listOf( 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/SessionState.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state 2 | 3 | import com.kortisan.framework.redux.state.caretaker.CaretakerStrategy 4 | import com.kortisan.framework.redux.state.caretaker.FileCaretakerStrategy 5 | import com.kortisan.framework.redux.state.productionrules.ProductionRule 6 | 7 | sealed class SessionState: ReduxState() { 8 | data class Logged ( val user: SessionState) : SessionState() { 9 | override val productionRules: List = sharedProductionRules } 10 | object LoggedOut: SessionState() { 11 | override val productionRules: List = sharedProductionRules } 12 | object Loading: SessionState() { 13 | override val productionRules: List = sharedProductionRules } 14 | 15 | protected val sharedProductionRules: List = listOf() 16 | override val caretakerStrategy: CaretakerStrategy? by lazy { 17 | FileCaretakerStrategy( defaultState = LoggedOut ) 18 | } 19 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/caretaker/DatastoreCaretakerStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.caretaker 2 | 3 | import com.kortisan.framework.redux.state.ReduxState 4 | 5 | class DatastoreCaretakerStrategy( 6 | override val defaultState: ReduxState 7 | ): CaretakerStrategy() { 8 | override fun persist(currentState: ReduxState) { 9 | TODO("Not yet implemented") 10 | } 11 | 12 | override fun recover(stateClassName: String): ReduxState? { 13 | TODO("Not yet implemented") 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/caretaker/RoomCaretakerStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.caretaker 2 | 3 | import com.kortisan.framework.redux.state.ReduxState 4 | 5 | class RoomCaretakerStrategy( 6 | override val defaultState: ReduxState 7 | ): CaretakerStrategy() { 8 | override fun persist(currentState: ReduxState) { 9 | TODO("Not yet implemented") 10 | } 11 | 12 | override fun recover(stateClassName: String): ReduxState? { 13 | TODO("Not yet implemented") 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/productionrules/ProductionRule.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.productionrules 2 | 3 | import com.kortisan.framework.redux.actions.ReduxAction 4 | import com.kortisan.framework.redux.state.ReduxState 5 | 6 | /** * * * * * * * * * 7 | * Project KoreFrame 8 | * Created by Jacobo G Tamayo on 03/01/23. 9 | * * * * * * * * * * **/ 10 | 11 | /** 12 | * Regla de porducción base, recibe un estado y una acción; produce un nuevo estado. 13 | * @see ReduxAction 14 | * @see ReduxState 15 | */ 16 | typealias ProductionRule = (ReduxState, ReduxAction) -> ReduxState -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/productionrules/dsl/ProductionRuleDSL.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.productionrules.dsl 2 | 3 | /** * * * * * * * * * 4 | * Project DemoAppKoreFrame 5 | * Created by jacobo on 30/mar./2024. 6 | * * * * * * * * * * **/ 7 | 8 | /** 9 | * EJEMPLO (PENDIENTE VALIDAR): 10 | * 11 | nextNode( currentState ) { 12 | when { actionDispatched } 13 | 14 | resultState { 15 | success -> NewState, 16 | fail -> NewStateFail // Opcional 17 | } 18 | 19 | validations { // Opcional 20 | field( "Email" ) { 21 | emailFormat { } 22 | minLength { 10 } 23 | } 24 | } 25 | } 26 | */ -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/validations/StateValidationResult.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.validations 2 | 3 | /** * * * * * * * * * 4 | * Project DemoAppKoreFrame 5 | * Created by jacobo on 24/mar./2024. 6 | * * * * * * * * * * **/ 7 | 8 | /** 9 | * Wrapper para los resultados de la validación de un estado. 10 | */ 11 | sealed class StateValidationResult { 12 | /** 13 | * Validación con resultado exitoso 14 | */ 15 | data object SuccessResult: StateValidationResult() 16 | 17 | /** 18 | * Validación con errores 19 | */ 20 | data class ErrorResult( 21 | val errorList: List 22 | ): StateValidationResult() 23 | } 24 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/validations/rules/ValidateEmailFormatRule.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.validations.rules 2 | 3 | import com.kortisan.framework.redux.state.validations.ValidationRule 4 | 5 | /** * * * * * * * * * 6 | * Project DemoAppKoreFrame 7 | * Created by jacobo on 24/mar./2024. 8 | * * * * * * * * * * **/ 9 | /** 10 | * Valida que el texto tenga el formato de email 11 | */ 12 | data class ValidateEmailFormatRule( 13 | var value: String, 14 | override val fieldName: String = "el campo" 15 | ): ValidationRule() { 16 | override var defaultErrorMessage: String = 17 | "El texto introducido ':value' en :field no corresponde con el formato de un email." 18 | 19 | override val placeHolderAlias: MutableMap = 20 | mutableMapOf( 21 | "value" to value, 22 | ) 23 | 24 | override fun passValidationRule(): Boolean { 25 | val regex = Regex("^[a-zA-Z0-9_!#\$%&’*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+\$") 26 | 27 | return value.matches( regex ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/validations/rules/ValidateMinLengthRule.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.validations.rules 2 | 3 | import com.kortisan.framework.redux.state.validations.ValidationRule 4 | 5 | /** * * * * * * * * * 6 | * Project DemoAppKoreFrame 7 | * Created by jacobo on 24/mar./2024. 8 | * * * * * * * * * * **/ 9 | data class ValidateMinLengthRule( 10 | var value: String, 11 | val minLength: Int = 1, 12 | override val fieldName: String = "" 13 | ): ValidationRule() { 14 | override val placeHolderAlias: MutableMap = mutableMapOf( 15 | "min" to "$minLength" 16 | ) 17 | 18 | override var defaultErrorMessage: String = 19 | "La longitud de :field es demasiado corta, debe ser de al menos :min caracteres" 20 | 21 | override fun passValidationRule(): Boolean { 22 | return value.length > minLength 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/redux/state/validations/rules/ValidateNotEmptyRule.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.redux.state.validations.rules 2 | 3 | import com.kortisan.framework.redux.state.validations.ValidationRule 4 | 5 | /** * * * * * * * * * 6 | * Project DemoAppKoreFrame 7 | * Created by jacobo on 24/mar./2024. 8 | * * * * * * * * * * **/ 9 | data class ValidateNotEmptyRule( 10 | var value: String, 11 | override val fieldName: String = "", 12 | ): ValidationRule() { 13 | override var defaultErrorMessage: String = 14 | "El campo :field no puede ir vacío" 15 | 16 | override fun passValidationRule(): Boolean { 17 | return value.isNotBlank() || value.isNotEmpty() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/services/location/KoreLocationService.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.services.location 2 | 3 | import android.app.Service 4 | import android.content.Intent 5 | import android.content.res.Configuration 6 | import android.os.IBinder 7 | 8 | class KoreLocationService: Service() { 9 | override fun onBind(p0: Intent?): IBinder? { 10 | TODO("Not yet implemented") 11 | } 12 | 13 | override fun onCreate() { 14 | super.onCreate() 15 | } 16 | 17 | override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 18 | return super.onStartCommand(intent, flags, startId) 19 | } 20 | 21 | override fun onConfigurationChanged(newConfig: Configuration) { 22 | super.onConfigurationChanged(newConfig) 23 | } 24 | 25 | override fun onRebind(intent: Intent?) { 26 | super.onRebind(intent) 27 | } 28 | 29 | override fun onUnbind(intent: Intent?): Boolean { 30 | return super.onUnbind(intent) 31 | } 32 | 33 | override fun onDestroy() { 34 | super.onDestroy() 35 | } 36 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/services/mediaplayer/MediaPlayerService.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.services.mediaplayer 2 | 3 | /** * * * * * * * * * 4 | * Project KoreFrame 5 | * Created by Jacobo G Tamayo on 06/01/23. 6 | * * * * * * * * * * **/ 7 | class MediaPlayerService { 8 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/services/voiceinteraction/VoiceCommandInteractionService.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.services.voiceinteraction 2 | 3 | import android.service.voice.VoiceInteractionService 4 | 5 | /** * * * * * * * * * 6 | * Project KoreFrame 7 | * Created by Jacobo G Tamayo on 06/01/23. 8 | * * * * * * * * * * **/ 9 | class VoiceCommandInteractionService: VoiceInteractionService() { 10 | override fun onReady() { 11 | super.onReady() 12 | } 13 | 14 | override fun onGetSupportedVoiceActions(voiceActions: MutableSet): MutableSet { 15 | return super.onGetSupportedVoiceActions(voiceActions) 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/services/voiceinteraction/VoiceCommandInteractionSession.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.services.voiceinteraction 2 | 3 | import android.content.Context 4 | import android.os.Bundle 5 | import android.service.voice.VoiceInteractionSession 6 | 7 | /** * * * * * * * * * 8 | * Project KoreFrame 9 | * Created by Jacobo G Tamayo on 06/01/23. 10 | * * * * * * * * * * **/ 11 | class VoiceCommandInteractionSession( context: Context ): VoiceInteractionSession( context ) { 12 | override fun onShow(args: Bundle?, showFlags: Int) { 13 | super.onShow(args, showFlags) 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/services/voiceinteraction/VoiceCommandInteractionSessionService.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.services.voiceinteraction 2 | 3 | import android.os.Bundle 4 | import android.service.voice.VoiceInteractionSession 5 | import android.service.voice.VoiceInteractionSessionService 6 | 7 | /** * * * * * * * * * 8 | * Project KoreFrame 9 | * Created by Jacobo G Tamayo on 06/01/23. 10 | * * * * * * * * * * **/ 11 | class VoiceCommandInteractionSessionService: VoiceInteractionSessionService() { 12 | override fun onNewSession(p0: Bundle?): VoiceInteractionSession { 13 | TODO("Not yet implemented") 14 | } 15 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/database/TypeConverters.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.database 2 | 3 | import androidx.room.TypeConverter 4 | import java.util.* 5 | 6 | class TypeConverters { 7 | @TypeConverter 8 | fun fromTimestamp(value: Long?): Date? = 9 | value?.let { Date(it) } 10 | 11 | @TypeConverter 12 | fun dateToTimestamp(date: Date?): Long? = 13 | date?.time 14 | 15 | @TypeConverter 16 | fun arrayIntToString(intList: ArrayList?): String? = 17 | intList?.joinToString(";") 18 | 19 | @TypeConverter 20 | fun arrayStringToString(array: ArrayList?): String? = 21 | array?.joinToString(",") 22 | 23 | @TypeConverter 24 | fun stringToArrayInt(stringList: String?): ArrayList = 25 | stringList?.let { 26 | if(it.isNotEmpty()) 27 | it.split(";") 28 | .mapTo(ArrayList()) { split -> split.toInt() } 29 | else null 30 | } ?: arrayListOf() 31 | 32 | @TypeConverter 33 | fun stringToArrayString(string: String?): ArrayList = 34 | string?.let { s -> 35 | if(s.isNotEmpty()) 36 | return s.split(",").mapTo(ArrayList()) { it } 37 | else null 38 | } ?: arrayListOf() 39 | } 40 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/database/dao/BaseDao.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.database.dao 2 | 3 | import androidx.room.Delete 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Update 7 | 8 | interface BaseDao { 9 | @Insert(onConflict = OnConflictStrategy.REPLACE) 10 | fun insertUnsafe(obj: T): Long 11 | 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insertUnsafe(vararg obj: T) 14 | 15 | @Insert(onConflict = OnConflictStrategy.REPLACE) 16 | fun insertAllUnsafe(list: List) 17 | 18 | @Update(onConflict = OnConflictStrategy.REPLACE) 19 | fun updateAllUnsafe(list: List) 20 | 21 | @Delete 22 | fun delete(obj: T) 23 | 24 | @Update 25 | fun updateUnsafe(obj: T): Int 26 | } 27 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/database/dao/SecurityLayerDao.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.database.dao 2 | 3 | 4 | import com.kortisan.framework.storage.security.SecurityStrategy 5 | import kotlinx.coroutines.flow.Flow 6 | import kotlinx.coroutines.flow.transform 7 | 8 | open class SecurityLayerDao { 9 | open fun encryptModel(inputData: T, strategy: SecurityStrategy): T = inputData 10 | open fun decryptModel(inputData: T, strategy: SecurityStrategy): T = inputData 11 | 12 | open fun safeInsert(inputData: T, strategy: SecurityStrategy) { /* Inserción segura */ } 13 | open fun safeSelect(inputData: T, strategy: SecurityStrategy): T = inputData 14 | 15 | fun safeSelect(inputData: Flow, strategy: SecurityStrategy): Flow = 16 | inputData.transform { safeSelect(it, strategy) } 17 | 18 | fun safeSelectList(inputData: Flow>, strategy: SecurityStrategy): Flow> = 19 | inputData.transform { list -> list.map { safeSelect(it, strategy) } } 20 | } 21 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/datastore/DataStoreBinding.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.datastore 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Context 8 | import androidx.datastore.core.DataStore 9 | import androidx.datastore.dataStore 10 | import com.kortisan.framework.storage.local.datastore.serializers.DynamicKeysVaultStoreSerializer 11 | import com.kortisan.framework.storage.local.datastore.serializers.TokensVaultStoreSerializer 12 | 13 | val Context.dynamicKeysVaultStore: DataStore by dataStore( 14 | fileName = "dynamicKeysDataStore.pb", 15 | serializer = DynamicKeysVaultStoreSerializer 16 | ) 17 | 18 | val Context.tokensVaultStore: DataStore by dataStore( 19 | fileName = "tokensVaultStore.pb", 20 | serializer = TokensVaultStoreSerializer 21 | ) 22 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/datastore/DataStoreSecureInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.datastore 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Context 8 | import com.kortisan.framework.storage.security.SecurityStrategy 9 | 10 | import kotlinx.coroutines.flow.Flow 11 | 12 | /** 13 | * Interfaz para obtener y leer la información de un datastore utilizando una estrategia de 14 | * seguridad como intermediaria. 15 | * 16 | * El tipo T es antes de la encriptación y/o después de la des encriptación. 17 | * Normalmente el tipo T es una entidad de la aplicación. 18 | */ 19 | interface DataStoreSecureInterface { 20 | fun getData( context: Context, strategy: SecurityStrategy): Flow 21 | suspend fun setData( context: Context, inputData: T, strategy: SecurityStrategy) 22 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/datastore/serializers/DynamicKeysVaultStoreSerializer.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.datastore.serializers 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import androidx.datastore.core.CorruptionException 8 | import androidx.datastore.core.Serializer 9 | import com.kortisan.framework.storage.local.datastore.DynamicKeysVaultStore 10 | import java.io.IOException 11 | import java.io.InputStream 12 | import java.io.OutputStream 13 | 14 | object DynamicKeysVaultStoreSerializer: Serializer { 15 | override val defaultValue: DynamicKeysVaultStore 16 | get() = DynamicKeysVaultStore.getDefaultInstance() 17 | 18 | override suspend fun readFrom(input: InputStream): DynamicKeysVaultStore { 19 | try { 20 | return DynamicKeysVaultStore.parseFrom( input ) 21 | } catch (e: IOException) { 22 | throw CorruptionException("No se puede leer proto de DynamicKeysVaultStore", e) 23 | } 24 | } 25 | 26 | override suspend fun writeTo(t: DynamicKeysVaultStore, output: OutputStream) = 27 | t.writeTo( output ) 28 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/datastore/serializers/TokensVaultStoreSerializer.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.datastore.serializers 2 | 3 | /** * * * * * * * * * 4 | * Project KoreFrame 5 | * Created by Jacobo G Tamayo on 30/12/22. 6 | * * * * * * * * * * **/ 7 | import androidx.datastore.core.CorruptionException 8 | import androidx.datastore.core.Serializer 9 | import com.kortisan.framework.storage.local.datastore.TokensVaultStore 10 | import java.io.IOException 11 | import java.io.InputStream 12 | import java.io.OutputStream 13 | 14 | object TokensVaultStoreSerializer: Serializer { 15 | override val defaultValue: TokensVaultStore 16 | get() = TokensVaultStore.getDefaultInstance() 17 | 18 | override suspend fun readFrom(input: InputStream): TokensVaultStore { 19 | try { 20 | return TokensVaultStore.parseFrom( input ) 21 | } catch (e: IOException) { 22 | throw CorruptionException("No se puede leer proto de TokensVaultStore", e) 23 | } 24 | } 25 | 26 | override suspend fun writeTo(t: TokensVaultStore, output: OutputStream) = t.writeTo( output ) 27 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/local/datastore/vaults/DynamicKeysVaultStoreSecure.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.local.datastore.vaults 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.content.Context 8 | import com.kortisan.framework.storage.local.datastore.DynamicKeysVaultStore 9 | import com.kortisan.framework.storage.security.SecurityStrategy 10 | import com.kortisan.framework.entities.DynamicKeys 11 | import com.kortisan.framework.storage.local.datastore.DataStoreSecureInterface 12 | import com.kortisan.framework.storage.local.datastore.dynamicKeysVaultStore 13 | import kotlinx.coroutines.flow.Flow 14 | import kotlinx.coroutines.flow.map 15 | 16 | object DynamicKeysVaultStoreSecure: DataStoreSecureInterface { 17 | override fun getData(context: Context, strategy: SecurityStrategy): Flow = 18 | context.dynamicKeysVaultStore.data.map { dynamicKeysVaultStore: DynamicKeysVaultStore -> 19 | DynamicKeys( 20 | aesPrivate = strategy.decrypt( dynamicKeysVaultStore.aesUnsafePrivate ), 21 | aesPublic = strategy.decrypt( dynamicKeysVaultStore.aesUnsafePublic ), 22 | ) 23 | } 24 | 25 | override suspend fun setData( 26 | context: Context, 27 | inputData: DynamicKeys, 28 | strategy: SecurityStrategy 29 | ) { 30 | context.dynamicKeysVaultStore.updateData { dynamicKeysVaultStore: DynamicKeysVaultStore -> 31 | dynamicKeysVaultStore.toBuilder() 32 | .setAesUnsafePrivate( strategy.encrypt( inputData.aesPrivate )) 33 | .setAesUnsafePublic( strategy.encrypt( inputData.aesPublic )) 34 | .build() 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/ApiClient.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import com.kortisan.framework.storage.remote.webservices.client.interceptors.apiInterfaces.AuthenticationApiInterface 8 | import com.kortisan.framework.storage.remote.webservices.client.strategies.* 9 | import retrofit2.Retrofit 10 | import retrofit2.converter.gson.GsonConverterFactory 11 | 12 | object APIClient { 13 | private val retrofit = Retrofit.Builder() 14 | .addConverterFactory(GsonConverterFactory.create()) 15 | 16 | fun buildService( service: Class, strategy: ClientBuilderStrategy 17 | = NoInterceptorStrategy ): T { 18 | return retrofit 19 | .baseUrl( strategy.baseUrl ) 20 | .client( strategy.client ) 21 | .build() 22 | .create( service ) 23 | } 24 | 25 | fun authenticationService(): AuthenticationApiInterface = 26 | buildService( 27 | AuthenticationApiInterface::class.java, 28 | NoInterceptorStrategy 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/EndPoints.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | sealed class EndPoints { 8 | object Authentication: EndPoints() { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/interceptors/apiInterfaces/AuthenticationApiInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.interceptors.apiInterfaces 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | interface AuthenticationApiInterface { 8 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/interceptors/application/AuthInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.interceptors.application 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import okhttp3.Interceptor 8 | import okhttp3.Response 9 | 10 | class AuthInterceptor: Interceptor { 11 | override fun intercept(chain: Interceptor.Chain): Response { 12 | val request = chain.request().newBuilder() 13 | 14 | return chain.proceed( 15 | request.build() 16 | ) 17 | } 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/interceptors/application/HttpCodeInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.interceptors.application 2 | 3 | import okhttp3.Interceptor 4 | import okhttp3.MediaType.Companion.toMediaType 5 | import okhttp3.Response 6 | import okhttp3.ResponseBody.Companion.toResponseBody 7 | import org.json.JSONObject 8 | 9 | /** * * * * * * * * * 10 | * Project KoreFrame 11 | * Created by Jacobo G Tamayo on 06/01/23. 12 | * * * * * * * * * * **/ 13 | /** 14 | * Intercepta la petición y agrega el código HTTP a la respuesta obtenida 15 | */ 16 | class HttpCodeInterceptor: Interceptor { 17 | override fun intercept(chain: Interceptor.Chain): Response { 18 | // Obtenemos la petición 19 | val request = chain.request() 20 | 21 | // Procesamos la petición y obtenemos la respuesta 22 | val response = chain.proceed(request) 23 | 24 | val contentType = response.headers["Content-Type"] 25 | // Si la respuesta es de tipo JSON y tiene un código de éxito (2XX) 26 | if ( contentType == "application/json" ) { 27 | // Obtenemos el cuerpo de la respuesta en formato JSON 28 | response.body?.string()?.also { body -> 29 | val jsonObject = JSONObject(body) 30 | 31 | // Añadimos el código HTTP como un parámetro 32 | jsonObject.put("httpCode", response.code) 33 | 34 | // Convertimos el JSON modificado a una cadena y creamos un nuevo 35 | // cuerpo para la respuesta. 36 | val modifiedBody = jsonObject.toString().toResponseBody( 37 | body.toMediaType() 38 | ) 39 | 40 | // Creamos una nueva respuesta con el nuevo cuerpo 41 | return response.newBuilder().body( modifiedBody ).build() 42 | } 43 | } 44 | 45 | // Si la respuesta no es de tipo JSON o no tiene un código de éxito, retornamos 46 | // la respuesta original. 47 | return response 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/interceptors/network/Retry.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.interceptors.network 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import okhttp3.Interceptor 8 | import okhttp3.Response 9 | 10 | class Retry: Interceptor { 11 | override fun intercept(chain: Interceptor.Chain): Response { 12 | TODO("Not yet implemented") 13 | } 14 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/strategies/ClientBuilderStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.strategies 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | import okhttp3.OkHttpClient 7 | import okhttp3.logging.HttpLoggingInterceptor 8 | import java.util.concurrent.TimeUnit 9 | 10 | sealed class ClientBuilderStrategy { 11 | abstract val baseUrl: String 12 | abstract val client: OkHttpClient 13 | 14 | // 15 segundos para que falle la petición 15 | private val timeOut: Long = 15 16 | 17 | // Cliente base para todas las estrategias 18 | internal val _client = OkHttpClient.Builder() 19 | // En caso de ser necesario limitar la cantidad de peticiones simultaneas a 1 20 | // .dispatcher(Dispatcher().apply { 21 | // maxRequests = 1 22 | // maxRequestsPerHost = 1 23 | // }) 24 | .addInterceptor( 25 | HttpLoggingInterceptor().apply { 26 | level = HttpLoggingInterceptor.Level.BODY 27 | } 28 | ) 29 | .connectTimeout(timeOut, TimeUnit.SECONDS) 30 | .callTimeout(timeOut, TimeUnit.SECONDS) 31 | .readTimeout(timeOut, TimeUnit.SECONDS) 32 | .writeTimeout(timeOut, TimeUnit.SECONDS) 33 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/client/strategies/NoInterceptorStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.client.strategies 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import okhttp3.OkHttpClient 8 | 9 | /** 10 | * Estrategia libre de interceptores 11 | */ 12 | object NoInterceptorStrategy: ClientBuilderStrategy() { 13 | override val baseUrl: String = "" 14 | 15 | override val client: OkHttpClient 16 | get() = _client 17 | .build() 18 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/dto/BaseRequest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.dto 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | open class BaseRequest ( 8 | // open var message: String? = null, 9 | // open var error: String? = null, 10 | open var success: Boolean = false 11 | ) -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/dto/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.dto 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | open class BaseResponse ( 8 | // open var message: String? = null, 9 | // open var error: String? = null, 10 | open var success: Boolean = false 11 | ) 12 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/remote/webservices/dto/PersistentResponseInterface.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.remote.webservices.dto 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | interface PersistentResponseInterface { 8 | fun toDatabaseModel(): T 9 | fun toDatastore(): S 10 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/repositories/RepositoryUtils.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.repositories 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import kotlinx.coroutines.flow.* 8 | import kotlinx.coroutines.CoroutineDispatcher 9 | import kotlinx.coroutines.Dispatchers 10 | import kotlinx.coroutines.delay 11 | 12 | /** 13 | * Clase con utilidades para realizar las operaciones de los repositorios 14 | */ 15 | abstract class RepositoryUtils { 16 | open val dispatcher: CoroutineDispatcher = Dispatchers.IO 17 | /** 18 | * Algoritmo 7: Ejecución periodica con condición de salida 19 | */ 20 | fun periodicRun( 21 | task: suspend () -> T, 22 | finishCondition: suspend () -> Boolean, 23 | timeInSeconds: Long = 1L 24 | ): Flow = 25 | callbackFlow { 26 | do { 27 | send( task.invoke() ) 28 | 29 | delay( timeInSeconds ) 30 | } while( finishCondition.invoke() ) 31 | }.flowOn( dispatcher ) 32 | } 33 | -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/security/AesStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.security 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | import android.util.Base64 8 | import java.nio.charset.Charset 9 | import javax.crypto.Cipher 10 | import javax.crypto.spec.IvParameterSpec 11 | import javax.crypto.spec.SecretKeySpec 12 | 13 | object AesStrategy: SecurityStrategy() { 14 | private val publicKeyRequest = "" 15 | private val publicKeyResponse = "" 16 | private val privateKey = NativeKeysAccess.getAesPrivateKey() 17 | override val transformation = "AES/CBC/PKCS5Padding" 18 | 19 | override fun encrypt(value: String): String { 20 | if(value.isEmpty()) return "" 21 | 22 | return process( 23 | value = value.toByteArray(), 24 | mode = Cipher.ENCRYPT_MODE, 25 | key = SecretKeySpec( "$publicKeyRequest${ dynamicKeys.aesPrivate }".toByteArray(), "AES"), // unsafeAesRequest 26 | parameters = IvParameterSpec( hex2Binary(privateKey) ), 27 | preProcess = { message, cipher -> 28 | cipher.doFinal( message ) 29 | }, 30 | postProcess = { encodeBase64(it, Base64.URL_SAFE) } 31 | ) 32 | } 33 | 34 | override fun decrypt(value: String): String { 35 | if(value.isEmpty()) return "" 36 | 37 | return process( 38 | value = decodeBase64(value, Base64.URL_SAFE), 39 | mode = Cipher.DECRYPT_MODE, 40 | key = SecretKeySpec("$publicKeyRequest${ dynamicKeys.aesPublic }".toByteArray(), "AES"), // unsafeAesResponse 41 | parameters = IvParameterSpec( hex2Binary(privateKey) ), 42 | preProcess = { message, cipher -> 43 | cipher.doFinal( message ) 44 | }, 45 | postProcess = { 46 | String( it, Charset.defaultCharset() ) 47 | } 48 | ) 49 | } 50 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/security/NativeKeysAccess.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.security 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | object NativeKeysAccess { 8 | fun getAesPrivateKey(): String = "XYZ" 9 | } -------------------------------------------------------------------------------- /framework/src/main/java/com/kortisan/framework/storage/security/NoSecurityStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework.storage.security 2 | /** * * * * * * * * * 3 | * Project KoreFrame 4 | * Created by Jacobo G Tamayo on 30/12/22. 5 | * * * * * * * * * * **/ 6 | 7 | /** 8 | * Estrategia que no implementa ningún tipo de seguridad 9 | */ 10 | object NoSecurityStrategy: SecurityStrategy() { 11 | override val transformation: String = "" 12 | 13 | override fun encrypt(value: String): String { 14 | return value 15 | } 16 | 17 | override fun decrypt(value: String): String { 18 | return value 19 | } 20 | } -------------------------------------------------------------------------------- /framework/src/main/proto/DynamicKeysVaultStore.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; option java_package = "com.kortisan.framework.storage.local.datastore"; option java_multiple_files = true; message DynamicKeysVaultStore { string aesUnsafePublic = 1; string aesUnsafePrivate = 2; } -------------------------------------------------------------------------------- /framework/src/main/proto/TokensVaultStore.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_package = "com.kortisan.framework.storage.local.datastore"; 4 | option java_multiple_files = true; 5 | 6 | message TokensVaultStore { 7 | string bearer = 1; 8 | string bearerAge = 2; 9 | string bearerExpireTime = 3; 10 | 11 | string user = 4; 12 | string userAge = 5; 13 | string userExpireTime = 6; 14 | 15 | string refresh = 7; 16 | string refreshAge = 8; 17 | string refreshExpireTime = 9; 18 | } -------------------------------------------------------------------------------- /framework/src/main/res/drawable/error_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /framework/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Servicio de detección de comandos de voz de KoreFrame 4 | -------------------------------------------------------------------------------- /framework/src/test/java/com/kortisan/framework/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.framework 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true 24 | android.nonFinalResIds=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jan 06 02:05:25 CST 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /ksp/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /ksp/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias( libs.plugins.kotlin.jvm ) 3 | } 4 | 5 | java { 6 | sourceCompatibility = JavaVersion.VERSION_21 7 | targetCompatibility = JavaVersion.VERSION_21 8 | } 9 | 10 | //sourceSets.main { 11 | // java.srcDirs("src/main/kotlin") 12 | //} 13 | 14 | kotlin { 15 | sourceSets.main { 16 | kotlin.srcDir("build/generated/ksp/main/kotlin") 17 | } 18 | sourceSets.test { 19 | kotlin.srcDir("build/generated/ksp/test/kotlin") 20 | } 21 | } 22 | 23 | dependencies { 24 | // PROCESADOR DE ANOTACIONES 25 | implementation "com.google.devtools.ksp:symbol-processing-api:2.0.0-1.0.21" 26 | implementation "com.squareup:kotlinpoet:1.14.2" 27 | } -------------------------------------------------------------------------------- /ksp/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cobogt/kortisan-android-framework/3d072c6c5f0a2ab19dd7ae2d8f3999ffd6bc7709/ksp/consumer-rules.pro -------------------------------------------------------------------------------- /ksp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /ksp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | @Target( AnnotationTarget.CLASS ) 4 | @Retention( AnnotationRetention.SOURCE ) 5 | annotation class FlowNameActivity( 6 | /** 7 | * Name to identify this activity 8 | */ 9 | val flowName: String, 10 | /** 11 | * Path to find this activity, optional 12 | */ 13 | val path: String = "", 14 | ) -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameClass.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | /** * * * * * * * * * 4 | * Project DemoAppKoreFrame 5 | * Created by jacobo on 08/jun./2024. 6 | * * * * * * * * * * **/ 7 | annotation class FlowNameClass( 8 | 9 | ) 10 | -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameCompose.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | @Target( AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.EXPRESSION) 4 | @Retention(AnnotationRetention.SOURCE) 5 | annotation class FlowNameCompose( 6 | val activityClassName: String, 7 | val flowName: String, 8 | // Lista de gates 9 | ) 10 | -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameExternal.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | /** * * * * * * * * * 4 | * Project DemoAppKoreFrame 5 | * Created by jacobo on 08/jun./2024. 6 | * * * * * * * * * * **/ 7 | annotation class FlowNameExternal() 8 | -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | import com.google.devtools.ksp.processing.Dependencies 4 | import com.google.devtools.ksp.processing.Resolver 5 | import com.google.devtools.ksp.processing.SymbolProcessor 6 | import com.google.devtools.ksp.processing.SymbolProcessorEnvironment 7 | import com.google.devtools.ksp.symbol.KSAnnotated 8 | import com.google.devtools.ksp.symbol.KSClassDeclaration 9 | import com.google.devtools.ksp.validate 10 | import kotlin.reflect.KClass 11 | 12 | /** 13 | * When called from a module, it looks for all the annotations of flownames and creates the 14 | * directories for the NavigationController. 15 | */ 16 | class FlowNameProcessor( 17 | private val environment: SymbolProcessorEnvironment 18 | ): SymbolProcessor { 19 | private fun Resolver.findAnnotations( 20 | kClass: KClass<*>, 21 | ) = getSymbolsWithAnnotation( 22 | kClass.qualifiedName.toString()) 23 | .filterIsInstance() 24 | 25 | override fun process(resolver: Resolver): List { 26 | // Detects all flownames for activities 27 | val listedActivities: Sequence = 28 | resolver.findAnnotations(FlowNameActivity::class) 29 | 30 | if( ! listedActivities.iterator().hasNext() ) 31 | return emptyList() 32 | 33 | val activityNames = listedActivities.map{ it.simpleName.asString() } 34 | // val sourceFiles = listedActivities.mapNotNull { it.containingFile } 35 | 36 | val fileText = buildString { 37 | append("// ") 38 | append(activityNames.joinToString(", ")) 39 | } 40 | 41 | val file = environment 42 | .codeGenerator 43 | .createNewFile( 44 | Dependencies(false), 45 | "com.kortisan.framework.redux.controllers.navigation.routeExplorer", 46 | "GeneratedLists", 47 | ) 48 | 49 | file.write(fileText.toByteArray()) 50 | file.close() 51 | 52 | return (listedActivities).filterNot { it.validate() }.toList() 53 | } 54 | } -------------------------------------------------------------------------------- /ksp/src/main/java/com/kortisan/ksp/annotations/FlowNameProcessorProvider.kt: -------------------------------------------------------------------------------- 1 | package com.kortisan.ksp.annotations 2 | 3 | import com.google.devtools.ksp.processing.SymbolProcessor 4 | import com.google.devtools.ksp.processing.SymbolProcessorEnvironment 5 | import com.google.devtools.ksp.processing.SymbolProcessorProvider 6 | 7 | class FlowNameProcessorProvider: SymbolProcessorProvider { 8 | override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { 9 | return FlowNameProcessor(environment) 10 | } 11 | } -------------------------------------------------------------------------------- /ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider: -------------------------------------------------------------------------------- 1 | com.kortisan.ksp.annotations.FlowNameProcessorProvider -------------------------------------------------------------------------------- /projectBuildSettings/dependencyHierarchy.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Archivo de referencia para identificar las dependencias del proyecto. 3 | * 4 | * Content << Framework 5 | */ -------------------------------------------------------------------------------- /projectBuildSettings/detectAndJoinKSP.gradle: -------------------------------------------------------------------------------- 1 | tasks.register("detectAndJoinKSP") { 2 | doLast { 3 | println "detectAndJoinKSP is running NOW" 4 | } 5 | } -------------------------------------------------------------------------------- /projectBuildSettings/projectBuild.gradle: -------------------------------------------------------------------------------- 1 | // Importamos la configuración del proyecto 2 | apply from: "$rootDir.path/projectBuildSettings/projectConfig.gradle" 3 | apply from: "$rootDir.path/projectBuildSettings/projectBuildTypes.gradle" 4 | apply from: "$rootDir.path/projectBuildSettings/projectFlavors.gradle" 5 | 6 | android { 7 | compileSdkVersion 35 8 | defaultConfig { 9 | compileSdkVersion 35 10 | } 11 | 12 | flavorDimensions "platform" 13 | 14 | // Flavors (Variables dependientes de la compilación) 15 | productFlavors { 16 | projectFlavors() 17 | } 18 | 19 | buildTypes { 20 | projectBuildTypes() 21 | } 22 | 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_21 25 | targetCompatibility JavaVersion.VERSION_21 26 | } 27 | kotlinOptions { 28 | jvmTarget = '21' 29 | } 30 | 31 | buildFeatures { 32 | compose true 33 | } 34 | } 35 | 36 | // Importamos todas las librerías y binarios 37 | //dependencies { 38 | // implementation fileTree(include: ['*.jar'], dir: 'libs') 39 | //} 40 | 41 | // Importamos las dependencias del proyecto 42 | apply from: "$rootDir.path/projectBuildSettings/projectDependencies.gradle" -------------------------------------------------------------------------------- /projectBuildSettings/projectBuildTypes.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Opciones de construcción disponibles en el proyecto 3 | */ 4 | ext.projectBuildTypes = { 5 | return { 6 | release { 7 | minifyEnabled false 8 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 9 | buildConfigField "Boolean", "IS_DEBUG", "false" 10 | } 11 | 12 | debug { 13 | minifyEnabled false 14 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 15 | buildConfigField "Boolean", "IS_DEBUG", "true" 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /projectBuildSettings/projectConfig.gradle: -------------------------------------------------------------------------------- 1 | ext.projectGradleConfig = [ 2 | applicationId: "com.kortisan.demoapp", 3 | targetSdkVersion: 35, 4 | compileSdk: 36, 5 | compileSdkVersion: 35, 6 | minSdkVersion: 26, 7 | versionCode: 1, 8 | revisionCode: 1, 9 | fixCode: 1, 10 | launchVersionCodeName: "Alfa", 11 | ] 12 | 13 | def projectConfig = ext.projectGradleConfig 14 | 15 | ext.getVersionCode = { 16 | return (projectConfig.versionCode * 1000) + 17 | (projectConfig.revisionCode * 10) + 18 | projectConfig.fixCode 19 | } 20 | 21 | ext.getVersionName = { 22 | String versionName = (projectConfig.versionCode * 1000) + "." + 23 | (projectConfig.revisionCode * 10) + "." + 24 | projectConfig.fixCode + "_" + 25 | projectConfig.launchVersionCodeName 26 | 27 | return versionName 28 | } -------------------------------------------------------------------------------- /projectBuildSettings/projectDependenciesFramework.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Este archivo incluye todas las dependencias disponibles solo para el framework base 3 | * Idealmente no serán necesarias en los módulo de contenido 4 | */ 5 | 6 | dependencies { 7 | // FIREBASE 8 | implementation platform(libs.firebase.bom) 9 | implementation libs.firebase.messaging.ktx 10 | implementation libs.firebase.config 11 | implementation libs.firebase.analytics 12 | implementation libs.firebase.common.ktx 13 | 14 | // SERVICIOS DE GOOGLE 15 | // ADVERTENCIA: ACTUALIZAR A 4.4.0 GENERA CONFLICTO CON PROTOBUF 16 | implementation libs.google.services 17 | 18 | // REFLEXIÓN DE KOTLIN 19 | implementation libs.kotlin.reflect 20 | implementation libs.kotlin.stdlib.common 21 | 22 | // Actualización de la aplicación ???? 23 | // implementation libs.installreferrer 24 | // implementation libs.core.ktx 25 | 26 | // UTILITIES 27 | //implementation 'org.apache.commons:commons-lang3:3.12.0' 28 | implementation libs.commons.net 29 | implementation libs.joda.time 30 | 31 | // DEXTER: Permissions 32 | implementation libs.dexter 33 | 34 | // RETROFIT 35 | implementation libs.retrofit 36 | implementation libs.converter.gson 37 | 38 | // OKHTTP 39 | implementation libs.okhttp 40 | implementation libs.logging.interceptor 41 | testImplementation(libs.mockwebserver) 42 | 43 | // COMPOSE 44 | implementation libs.ui 45 | implementation libs.runtime 46 | 47 | // COMPOSE FOR ACTIVITIES 48 | implementation libs.activity.compose 49 | 50 | // MULTIDEX: 51 | // implementation 'androidx.multidex:multidex:2.0.1' 52 | 53 | // CRYPTO 54 | implementation libs.security.crypto 55 | implementation libs.biometric 56 | } -------------------------------------------------------------------------------- /projectBuildSettings/projectFlavors.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Flavors disponibles en el proyecto 3 | */ 4 | ext.projectFlavors = { 5 | return {} 6 | } -------------------------------------------------------------------------------- /projectBuildSettings/protobufSettings.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuración necesaria para la compilación de protobuf 3 | * 4 | * Los archivos .proto deben estar en la carpeta src/main/proto 5 | */ 6 | 7 | protobuf { 8 | protoc { 9 | artifact = "com.google.protobuf:protoc:4.29.2" 10 | } 11 | 12 | generateProtoTasks { 13 | all().each { task -> 14 | task.builtins { 15 | java { 16 | option 'lite' 17 | } 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | plugins { 3 | id("com.google.devtools.ksp") version "2.0.0-1.0.21" 4 | // id("com.google.devtools.ksp") version "1.8.0-1.0.8" 5 | } 6 | repositories { 7 | gradlePluginPortal() 8 | google() 9 | mavenCentral() 10 | } 11 | } 12 | dependencyResolutionManagement { 13 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 14 | repositories { 15 | gradlePluginPortal() 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.name = "DemoAppKoreFrame" 22 | include ':app' 23 | include ':content' 24 | include ':framework' 25 | include ':authentication' 26 | include ':ksp' 27 | 28 | --------------------------------------------------------------------------------