├── .gitignore ├── .gitlab-ci.yml ├── Code ├── Client │ ├── .gitignore │ ├── Android │ │ ├── .gitignore │ │ ├── android-client-shared │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidAndroidTest │ │ │ │ └── kotlin │ │ │ │ │ └── org │ │ │ │ │ └── chrishatton │ │ │ │ │ └── example │ │ │ │ │ └── common │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ │ ├── androidMain │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── org │ │ │ │ │ │ └── chrishatton │ │ │ │ │ │ └── example │ │ │ │ │ │ └── common │ │ │ │ │ │ ├── FirstFragment.kt │ │ │ │ │ │ └── package.kt │ │ │ │ └── res │ │ │ │ │ ├── layout │ │ │ │ │ └── fragment_first.xml │ │ │ │ │ └── values │ │ │ │ │ └── strings.xml │ │ │ │ └── androidTest │ │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ └── common │ │ │ │ └── ExampleUnitTest.kt │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── mobile │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidAndroidTest │ │ │ │ └── kotlin │ │ │ │ │ └── example │ │ │ │ │ └── ExampleInstrumentedTest.kt │ │ │ │ ├── androidMain │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── org │ │ │ │ │ │ └── chrishatton │ │ │ │ │ │ └── example │ │ │ │ │ │ └── mobile │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── res │ │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ ├── drawable │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ │ ├── layout │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── androidTest │ │ │ │ └── kotlin │ │ │ │ └── example │ │ │ │ └── ExampleUnitTest.kt │ │ ├── settings.gradle.kts │ │ └── tv │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ └── androidMain │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ └── tv │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ ├── app_icon_your_company.png │ │ │ ├── default_background.xml │ │ │ └── movie.png │ │ │ ├── layout │ │ │ ├── activity_details.xml │ │ │ └── activity_main.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── Browser │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle.kts │ ├── Desktop │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle.kts │ │ └── src │ │ │ ├── javafxMain │ │ │ ├── kotlin │ │ │ │ └── org │ │ │ │ │ └── chrishatton │ │ │ │ │ └── example │ │ │ │ │ ├── ExampleApp.kt │ │ │ │ │ └── NoteListView.kt │ │ │ └── resources │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ ├── NewNoteView.fxml │ │ │ │ ├── NoteListCell.fxml │ │ │ │ └── NoteListView.fxml │ │ │ └── test │ │ │ └── kotlin │ │ │ └── sample │ │ │ └── SampleTestsJavafx.kt │ ├── Shared │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ ├── AndroidManifest.xml │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ ├── ExampleClient.kt │ │ │ │ └── Platform.kt │ │ │ ├── androidTest │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ └── package.kt │ │ │ ├── commonMain │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ ├── ExampleClient.kt │ │ │ │ ├── Platform.kt │ │ │ │ └── ui │ │ │ │ ├── FirstContract.kt │ │ │ │ └── FirstPresenter.kt │ │ │ ├── commonTest │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ └── CommonPlatformTests.kt │ │ │ ├── iosMain │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ ├── ExampleClient.kt │ │ │ │ └── Platform.kt │ │ │ ├── javafxMain │ │ │ └── kotlin │ │ │ │ └── org │ │ │ │ └── chrishatton │ │ │ │ └── example │ │ │ │ ├── ExampleClient.kt │ │ │ │ └── Platform.kt │ │ │ └── javafxTest │ │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── package.kt │ ├── build.gradle.kts │ ├── client-shared.build.gradle.kts │ ├── client-shared.settings.gradle.kts │ └── iOS │ │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── Chris.xcuserdatad │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Example.xcscheme │ │ ├── Example │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── iosMain │ │ │ └── kotlin │ │ │ ├── example │ │ │ ├── AppDelegate.kt │ │ │ ├── BaseViewAdapter.kt │ │ │ └── FirstViewController.kt │ │ │ └── main.kt │ │ └── SupportingFiles │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ └── settings.gradle.kts ├── README.md ├── Server │ ├── .gitignore │ ├── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── renamePackage.kts │ ├── settings.gradle.kts │ ├── src │ │ ├── main │ │ │ ├── kotlin │ │ │ │ └── example │ │ │ │ │ └── Application.kt │ │ │ └── resources │ │ │ │ ├── application.conf │ │ │ │ └── logback.xml │ │ └── test │ │ │ └── kotlin │ │ │ └── example │ │ │ └── ApplicationTest.kt │ └── webapp │ │ └── WEB-INF │ │ └── web.xml ├── Shared │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ └── UUID.kt │ │ ├── androidTest │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── SampleTestsJVM.kt │ │ ├── browserMain │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ └── UUID.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ ├── Person.kt │ │ │ ├── UUID.kt │ │ │ └── api │ │ │ └── CRUD.kt │ │ ├── commonTest │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── SharedCommonTests.kt │ │ ├── iosMain │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ └── UUID.kt │ │ ├── iosTest │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── SharediOSTests.kt │ │ ├── javafxMain │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ └── UUID.kt │ │ ├── javafxTest │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ ├── SampleTestsJVM.kt │ │ │ └── package.kt │ │ ├── serverMain │ │ └── kotlin │ │ │ └── org │ │ │ └── chrishatton │ │ │ └── example │ │ │ └── model │ │ │ └── UUID.kt │ │ └── serverTest │ │ └── kotlin │ │ └── org │ │ └── chrishatton │ │ └── example │ │ ├── SampleTestsJVM.kt │ │ └── package.kt ├── build.gradle.kts ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties.template ├── renamePackage.kts ├── settings.gradle.kts ├── shared.gradle.kts ├── shared.properties └── shared.settings.gradle.kts ├── LICENSE.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Code/Client/app/build 2 | Code/Shared/build 3 | Code/Client/iOS/BM/build 4 | Code/Client/Common/build 5 | Code/Client/iOS/SupportingFiles/.gradle 6 | Code/Client/iOS/BM.xcodeproj/xcuserdata 7 | Code/Client/iOS/BM.xcodeproj/project.xcworkspace/xcuserdata 8 | Code/Client/Common/.gradle 9 | Code/.gradle 10 | Code/Client/Desktop/.gradle 11 | Code/Client/iOS/BM.xcodeproj/project.xcworkspace/xcshareddata 12 | *.iml 13 | Code/Client/iOS/Example.xcodeproj/xcuserdata 14 | Code/Client/iOS/Example/build 15 | Code/Client/iOS/Example.xcodeproj/project.xcworkspace/xcuserdata 16 | Code/Client/Desktop/build 17 | Code/Client/iOS/Example/.gradle 18 | Code/Build/buildSrc/.gradle 19 | Code/Build/buildSrc/.gradle 20 | Code/Client/Common/multi-mvp/.gradle 21 | Code/Client/Common/multi-mvp/build 22 | Code/Client/Shared/.gradle 23 | Code/Client/Shared/build 24 | Code/Lib/multi-mvp/.gradle 25 | Code/Lib/multi-mvp/build 26 | Code/Lib/coroutines-ui/.gradle 27 | Code/Lib/coroutines-ui/build 28 | Code/Client/iOS/SupportingFiles/build 29 | Code/Build 30 | Code/Client/Android/build-cache 31 | Code/Server/build-cache 32 | Code/Client/Desktop/build-cache 33 | Code/Client/iOS/SupportingFiles/build-cache 34 | Code/Lib/coroutines-ui/build 35 | Code/local.properties 36 | Code/Client/Browser/.gradle 37 | Code/Client/Browser/build 38 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | 2 | variables: 3 | GRADLE_OPTS: "-Dorg.gradle.daemon=false" 4 | 5 | before_script: 6 | - export GRADLE_USER_HOME=`pwd`/.gradle 7 | 8 | stages: 9 | - wakeBuildMachine 10 | - buildAndTest 11 | - publishLibs 12 | - deploy 13 | - shutdownBuildMachine 14 | 15 | wakeBuildMachine: 16 | stage: wakeBuildMachine 17 | tags: 18 | - small 19 | script: 20 | - ~/wakeRumpus.sh 21 | 22 | shutdownBuildMachine: 23 | stage: shutdownBuildMachine 24 | when: always 25 | tags: 26 | - small 27 | script: 28 | - ~/shutdownRumpus.sh 29 | 30 | buildAndTest: 31 | stage: buildAndTest 32 | tags: 33 | - large 34 | script: 35 | - cd Code 36 | - cp ~/Properties/MultiplatformTemplate/local.properties . 37 | - ./gradlew buildAndTestApp 38 | cache: 39 | key: "$CI_COMMIT_REF_NAME-App" 40 | policy: pull-push 41 | paths: 42 | - .gradle/wrapper 43 | - .gradle/caches 44 | - Code/Server/build 45 | - Code/Shared/build 46 | - Code/Lib/multi-mvp/build 47 | - Code/Client/Desktop/build 48 | - Code/Client/Shared/build 49 | - Code/Client/iOS/Example/build 50 | - Code/Client/iOS/SupportingFiles/build 51 | - Code/Client/Android/tv/build 52 | - Code/Client/Android/android-client-shared/build 53 | - Code/Client/Android/mobile/build 54 | - Code/Client/Android/build 55 | artifacts: 56 | name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" 57 | paths: 58 | - Code/Server/build/*.war 59 | - Code/Client/Desktop/build/*.zip 60 | - Code/Client/Android/tv/build/outputs/apk/**/*.apk 61 | - Code/Client/Android/mobile/build/outputs/apk/**/*.apk 62 | - Code/Client/iOS/Example/build/**/*.ipa 63 | # reports: 64 | # junit: 65 | # - Code/Server/build/reports/**/*.xml 66 | # - Code/Shared/build/reports/**/*.xml 67 | # - Code/Lib/multi-mvp/build/reports/**/*.xml 68 | # - Code/Client/Desktop/build/reports/**/*.xml 69 | # - Code/Client/Shared/build/reports/**/*.xml 70 | # - Code/Client/Android/android-client-shared/build/reports/**/*.xml 71 | # - Code/Client/Android/mobile/build/reports/**/*.xml 72 | 73 | publishLibs: 74 | tags: 75 | - large 76 | only: 77 | - master 78 | stage: publishLibs 79 | script: 80 | - cd Code 81 | - cp ~/Properties/MultiplatformTemplate/local.properties . 82 | - ./gradlew publishLibs 83 | cache: 84 | key: "${CI_COMMIT_REF_NAME}-App" 85 | policy: pull 86 | paths: 87 | - Code/Lib/coroutines-ui/build 88 | - Code/Lib/multi-mvp/build 89 | 90 | deploy-server: 91 | tags: 92 | - nas 93 | only: 94 | - master 95 | stage: deploy 96 | script: 97 | - cd Code 98 | - cp ~/Properties/MultiplatformTemplate/local.properties . 99 | - ./gradlew deployOnlyApp 100 | - cp Server/build/libs/Server-0.0.1.war /var/lib/jetty/webapps/root.war 101 | cache: 102 | key: "${CI_COMMIT_REF_NAME}-App" 103 | policy: pull 104 | paths: 105 | - Code/Server/build 106 | - Code/Shared/build 107 | 108 | environment: 109 | name: staging 110 | url: https://example.chrishatton.org/api/ 111 | 112 | # document-client: 113 | # only: 114 | # - master 115 | # stage: buildAndTest 116 | # script: 117 | # - cd Code 118 | # - cp ~/Properties/MultiplatformTemplate/local.properties . 119 | # - cd Client 120 | # - ./gradlew dokka 121 | # - rm -rf /usr/share/nginx/html/example/doc/client/* 122 | # - cp -R build/javadoc/client/* /usr/share/nginx/html/example/doc/client 123 | # - cp build/javadoc/style.css /usr/share/nginx/html/example/doc 124 | # cache: 125 | # key: "$CI_COMMIT_REF_NAME" 126 | # policy: pull 127 | # paths: 128 | # - build 129 | # - .gradle 130 | 131 | # Uses Kotlin's 'Dokka' plugin to generate and deploy documentation for the Server project 132 | # (including the supporting 'Shared' framework) 133 | document-server: 134 | tags: 135 | - nas 136 | only: 137 | - master 138 | stage: buildAndTest 139 | script: 140 | - cd Code 141 | - cp ~/Properties/MultiplatformTemplate/local.properties . 142 | - cd Server 143 | - ./gradlew dokka 144 | - mkdir -p /usr/share/nginx/html/example/doc/server/ 145 | - rm -rf /usr/share/nginx/html/example/doc/server/* 146 | - cp -R build/javadoc/server/* /usr/share/nginx/html/example/doc/server/ 147 | - cp build/javadoc/style.css /usr/share/nginx/html/example/doc/ 148 | cache: 149 | key: "${CI_COMMIT_REF_NAME}-App" 150 | policy: pull 151 | paths: 152 | - build 153 | - .gradle 154 | -------------------------------------------------------------------------------- /Code/Client/.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle 2 | /.idea 3 | /out 4 | /build 5 | *.iml 6 | *.ipr 7 | *.iws 8 | local.properties 9 | 10 | -------------------------------------------------------------------------------- /Code/Client/Android/.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 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /** 2 | * Build file for the 'Android-Client-shared' module of this Kotlin Multi-platform Application. 3 | * 4 | * Source files implemented in this module are accessible to all Android Client projects. 5 | * Currently this means to both the Android Mobile/Tablet module and the Android TV module. 6 | * Typically this module would be used to share common Fragments, custom Views or other parts 7 | * of the View layer (of the MVP architecture) which it is not desirable to re-implement 8 | * for both Android projects. 9 | */ 10 | 11 | apply( from = "../../../shared.gradle.kts") 12 | 13 | val androidBuildToolsVersion : String by extra 14 | val androidCompileSdkVersion : String by extra 15 | val androidTargetSdkVersion : String by extra 16 | val androidMinSdkVersion : String by extra 17 | 18 | plugins { 19 | id("com.android.library") 20 | id("org.jetbrains.kotlin.multiplatform") // We should be able to use `kotlin("android")` but Android Studio fails to resolve symbols from composite KMP libraries. 21 | id("kotlin-android-extensions") 22 | id("kotlinx-serialization") 23 | } 24 | 25 | val ccp = configurations.create("compileClasspath") 26 | configurations.add(ccp) 27 | 28 | android { 29 | buildToolsVersion = androidBuildToolsVersion 30 | 31 | compileSdkVersion(androidCompileSdkVersion.toInt()) 32 | defaultConfig { 33 | multiDexEnabled = true 34 | minSdkVersion(androidMinSdkVersion.toInt()) 35 | targetSdkVersion(androidTargetSdkVersion.toInt()) 36 | versionCode = 1 37 | versionName = "1.0" 38 | testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" 39 | } 40 | buildTypes { 41 | getByName("debug"){} 42 | getByName("release") { 43 | isMinifyEnabled = false 44 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 45 | } 46 | } 47 | packagingOptions { 48 | exclude("META-INF/ktor-http.kotlin_module") 49 | exclude("META-INF/kotlinx-io.kotlin_module") 50 | exclude("META-INF/atomicfu.kotlin_module") 51 | exclude("META-INF/ktor-utils.kotlin_module") 52 | exclude("META-INF/kotlinx-coroutines-io.kotlin_module") 53 | exclude("META-INF/kotlinx-coroutines-core.kotlin_module") 54 | exclude("META-INF/ktor-client-core.kotlin_module") 55 | exclude("META-INF/ktor-http-cio.kotlin_module") 56 | exclude("META-INF/ktor-io.kotlin_module") 57 | } 58 | sourceSets { 59 | this["main"].java.srcDir("src/androidMain/kotlin") 60 | this["test"].java.srcDir("src/androidTest/kotlin") 61 | this["androidTest"].java.srcDir("src/androidAndroidTest/kotlin") 62 | } 63 | lintOptions { 64 | isCheckReleaseBuilds = false 65 | isAbortOnError = false 66 | } 67 | } 68 | 69 | val multiMvp : String by extra 70 | 71 | val ktorClientAndroid : String by extra 72 | val ktorClientJson : String by extra 73 | 74 | val kotlinXCoroutinesAndroid : String by extra 75 | val androidXAppCompat : String by extra 76 | 77 | val jUnit : String by extra 78 | 79 | val clientSharedProject : ()->ProjectDependency by extra 80 | val sharedProject : ()->ProjectDependency by extra 81 | 82 | val androidXTestRunner : String by extra 83 | val androidXTestEspressoCore : String by extra 84 | 85 | val frameworkAttribute = Attribute.of("org.chrishatton.example.framework", String::class.java) 86 | 87 | kotlin { 88 | android("android") { 89 | attributes.attribute(frameworkAttribute, "android") 90 | publishLibraryVariants("release", "debug") // Required for Android to publish 91 | publishLibraryVariantsGroupedByFlavor = true 92 | } 93 | 94 | sourceSets { 95 | val androidMain by getting { 96 | dependencies { 97 | 98 | implementation(clientSharedProject()) 99 | implementation(sharedProject()) 100 | 101 | implementation(multiMvp) 102 | 103 | // Android 104 | implementation(kotlinXCoroutinesAndroid) 105 | implementation(androidXAppCompat) 106 | 107 | // Ktor 108 | implementation(ktorClientAndroid) 109 | implementation(ktorClientJson) 110 | } 111 | } 112 | 113 | val androidTest by getting { 114 | dependencies { 115 | // Test 116 | implementation(jUnit) 117 | 118 | // Android Test 119 | implementation(androidXTestRunner) 120 | implementation(androidXTestEspressoCore) 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/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.kts. 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 22 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/src/androidAndroidTest/kotlin/org/chrishatton/example/common/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package org.chrishatton.example.common; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | @Test 19 | public void useAppContext() { 20 | // Context of the app under test. 21 | Context appContext = InstrumentationRegistry.getTargetContext(); 22 | 23 | assertEquals("org.chrishatton.example", appContext.getPackageName()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/src/androidMain/kotlin/org/chrishatton/example/common/FirstFragment.kt: -------------------------------------------------------------------------------- 1 | package org.chrishatton.example.common 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import kotlinx.android.synthetic.main.fragment_first.* 8 | import kotlinx.android.synthetic.main.fragment_first.view.* 9 | import kotlinx.coroutines.InternalCoroutinesApi 10 | import org.chrishatton.example.ui.FirstContract 11 | import org.chrishatton.example.ui.FirstPresenter 12 | import org.chrishatton.multimvp.ui.BaseViewFragment 13 | 14 | @InternalCoroutinesApi 15 | @kotlinx.coroutines.ExperimentalCoroutinesApi 16 | class FirstFragment : BaseViewFragment(), 17 | FirstContract.View { 18 | 19 | override fun displayGreeting(text: String) { 20 | responseText.text = text 21 | } 22 | 23 | override val presenter : FirstPresenter by lazy { 24 | FirstPresenter( 25 | baseUrl = "http://10.0.2.2:8080", 26 | view = this 27 | ) 28 | } 29 | 30 | override fun onCreateView( 31 | inflater: LayoutInflater, container: ViewGroup?, 32 | savedInstanceState: Bundle? 33 | ): View? { 34 | // Inflate the layout for this fragment 35 | return inflater.inflate(R.layout.fragment_first, container, false).also { view -> 36 | view.sendButton.setOnClickListener { 37 | presenter.didSetName(nameEntry.text.toString()) 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/src/androidMain/kotlin/org/chrishatton/example/common/package.kt: -------------------------------------------------------------------------------- 1 | package org.chrishatton.example.common 2 | 3 | /* 4 | This package is for Android code common across the 'mobile' and 'TV' targets. 5 | It is expected that many Fragments and Activities will be viable across both targets, 6 | although some will benefit from UI/UX specialisation toward each differing format. 7 | */ 8 | -------------------------------------------------------------------------------- /Code/Client/Android/android-client-shared/src/androidMain/res/layout/fragment_first.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | 17 | 26 | 27 | 33 | 34 |