├── shared
├── src
│ ├── commonMain
│ │ └── kotlin
│ │ │ ├── Constants.kt
│ │ │ ├── Platform.kt
│ │ │ └── Greeting.kt
│ ├── jvmMain
│ │ └── kotlin
│ │ │ └── Platform.jvm.kt
│ ├── androidMain
│ │ └── kotlin
│ │ │ └── Platform.android.kt
│ └── iosMain
│ │ └── kotlin
│ │ └── Platform.ios.kt
└── build.gradle.kts
├── .kotlin
└── metadata
│ ├── kotlinTransformedCInteropMetadataLibraries
│ ├── .shared-iosMain.cinteropLibraries
│ ├── .shared-iosTest.cinteropLibraries
│ ├── .shared-appleMain.cinteropLibraries
│ ├── .shared-appleTest.cinteropLibraries
│ ├── .shared-nativeMain.cinteropLibraries
│ ├── .shared-nativeTest.cinteropLibraries
│ ├── io.ktor-ktor-utils-2.3.11-iosMain-cinterop
│ │ └── io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
│ ├── io.ktor-ktor-utils-2.3.12-iosMain-cinterop
│ │ └── io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
│ ├── org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop
│ │ └── org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
│ ├── org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop
│ │ └── org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
│ ├── .composeApp-appleMain.cinteropLibraries
│ ├── .composeApp-appleTest.cinteropLibraries
│ ├── .composeApp-iosMain.cinteropLibraries
│ ├── .composeApp-iosTest.cinteropLibraries
│ ├── .composeApp-nativeMain.cinteropLibraries
│ └── .composeApp-nativeTest.cinteropLibraries
│ └── kotlinTransformedMetadataLibraries
│ ├── io.ktor-ktor-io-2.3.11-posixMain-VFYQnA.klib
│ ├── io.ktor-ktor-io-2.3.12-posixMain-3YsjwQ.klib
│ ├── io.ktor-ktor-http-2.3.11-commonMain-QgEQ0Q.klib
│ ├── io.ktor-ktor-http-2.3.11-posixMain-QgEQ0Q.klib
│ ├── io.ktor-ktor-http-2.3.12-commonMain-W5sIeA.klib
│ ├── io.ktor-ktor-http-2.3.12-posixMain-W5sIeA.klib
│ ├── io.ktor-ktor-io-2.3.11-commonMain-VFYQnA.klib
│ ├── io.ktor-ktor-io-2.3.11-darwinMain-sbySvA.klib
│ ├── io.ktor-ktor-io-2.3.12-commonMain-3YsjwQ.klib
│ ├── io.ktor-ktor-io-2.3.12-darwinMain-sbySvA.klib
│ ├── io.ktor-ktor-utils-2.3.11-nixMain-kEcFvw.klib
│ ├── io.ktor-ktor-utils-2.3.11-posixMain-kEcFvw.klib
│ ├── io.ktor-ktor-utils-2.3.12-nixMain-kEcFvw.klib
│ ├── io.ktor-ktor-utils-2.3.12-posixMain-kEcFvw.klib
│ ├── com.squareup.okio-okio-3.9.0-unixMain-DWVyIA.klib
│ ├── com.squareup.okio-okio-3.9.0-zlibMain-DWVyIA.klib
│ ├── io.ktor-ktor-events-2.3.11-commonMain-_htHDg.klib
│ ├── io.ktor-ktor-events-2.3.12-commonMain-Q6-xkw.klib
│ ├── io.ktor-ktor-utils-2.3.11-commonMain-kEcFvw.klib
│ ├── io.ktor-ktor-utils-2.3.11-darwinMain-TE4abA.klib
│ ├── io.ktor-ktor-utils-2.3.12-commonMain-kEcFvw.klib
│ ├── io.ktor-ktor-utils-2.3.12-darwinMain-TE4abA.klib
│ ├── com.squareup.okio-okio-3.9.0-appleMain-BlIr1w.klib
│ ├── com.squareup.okio-okio-3.9.0-commonMain-DWVyIA.klib
│ ├── com.squareup.okio-okio-3.9.0-nativeMain-DWVyIA.klib
│ ├── com.squareup.okio-okio-3.9.0-nonJvmMain-DWVyIA.klib
│ ├── io.ktor-ktor-websockets-2.3.11-posixMain-8-9-_g.klib
│ ├── io.ktor-ktor-websockets-2.3.12-posixMain-8-9-_g.klib
│ ├── media.kamel-kamel-core-0.9.5-appleMain-aK6ixA.klib
│ ├── media.kamel-kamel-core-0.9.5-commonMain-WfPfow.klib
│ ├── media.kamel-kamel-image-0.9.5-appleMain-fGtM2w.klib
│ ├── media.kamel-kamel-image-0.9.5-commonMain-oIJf-w.klib
│ ├── media.kamel-kamel-image-0.9.5-nonJvmMain-oIJf-w.klib
│ ├── org.jetbrains.skiko-skiko-0.8.4-iosMain-1T2ZCw.klib
│ ├── com.squareup.okio-okio-3.9.0-hashFunctions-DWVyIA.klib
│ ├── io.ktor-ktor-client-core-2.3.11-commonMain-FU-9lg.klib
│ ├── io.ktor-ktor-client-core-2.3.11-posixMain-FU-9lg.klib
│ ├── io.ktor-ktor-client-core-2.3.12-commonMain-FU-9lg.klib
│ ├── io.ktor-ktor-client-core-2.3.12-posixMain-FU-9lg.klib
│ ├── io.ktor-ktor-websockets-2.3.11-commonMain-8-9-_g.klib
│ ├── io.ktor-ktor-websockets-2.3.12-commonMain-8-9-_g.klib
│ ├── org.jetbrains.skiko-skiko-0.8.4-commonMain-DbI_Jg.klib
│ ├── org.jetbrains.skiko-skiko-0.8.4-darwinMain-1T2ZCw.klib
│ ├── org.jetbrains.skiko-skiko-0.8.4-nativeMain-DbI_Jg.klib
│ ├── co.touchlab-stately-common-2.0.6-commonMain-WJbBBA.klib
│ ├── co.touchlab-stately-isolate-2.0.6-commonMain-4Bzzzg.klib
│ ├── co.touchlab-stately-strict-2.0.6-commonMain-0yIOhQ.klib
│ ├── io.ktor-ktor-client-darwin-2.3.11-darwinMain-CnRCQQ.klib
│ ├── io.ktor-ktor-client-darwin-2.3.12-darwinMain-CnRCQQ.klib
│ ├── io.ktor-ktor-serialization-2.3.11-commonMain-NxrIfg.klib
│ ├── io.ktor-ktor-serialization-2.3.12-commonMain-NxrIfg.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-commonMain-OrzU9w.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-darwinMain-OEwx0A.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-nativeMain-OEwx0A.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-skikoMain-OrzU9w.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-uikitMain-OEwx0A.klib
│ ├── org.jetbrains.skiko-skiko-0.8.4-nativeJsMain-DbI_Jg.klib
│ ├── androidx.annotation-annotation-1.8.0-commonMain-PJXh8Q.klib
│ ├── androidx.annotation-annotation-1.8.0-nonJvmMain-PJXh8Q.klib
│ ├── org.jetbrains.compose.ui-ui-1.6.11-jsNativeMain-OrzU9w.klib
│ ├── org.jetbrains.compose.ui-ui-unit-1.6.11-jbMain-vwDMdg.klib
│ ├── co.touchlab-stately-common-2.0.6-nativeCommonMain-WJbBBA.klib
│ ├── co.touchlab-stately-concurrency-2.0.6-commonMain-CAw19g.klib
│ ├── co.touchlab-stately-concurrency-2.0.6-darwinMain-oJtMMg.klib
│ ├── co.touchlab-stately-isolate-2.0.6-nativeCommonMain-4Bzzzg.klib
│ ├── co.touchlab-stately-strict-2.0.6-nativeCommonMain-0yIOhQ.klib
│ ├── com.squareup.okio-okio-3.9.0-systemFileSystemMain-DWVyIA.klib
│ ├── io.github.pdvrieze.xmlutil-core-0.86.3-commonMain-nC7WJg.klib
│ ├── io.github.pdvrieze.xmlutil-core-0.86.3-nativeMain-nC7WJg.klib
│ ├── org.jetbrains.compose.ui-ui-text-1.6.11-commonMain-aUvkxg.klib
│ ├── org.jetbrains.compose.ui-ui-text-1.6.11-darwinMain-DK5x5Q.klib
│ ├── org.jetbrains.compose.ui-ui-text-1.6.11-nativeMain-DK5x5Q.klib
│ ├── org.jetbrains.compose.ui-ui-text-1.6.11-skikoMain-aUvkxg.klib
│ ├── org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-oguluQ.klib
│ ├── org.jetbrains.compose.ui-ui-unit-1.6.11-commonMain-vwDMdg.klib
│ ├── org.jetbrains.compose.ui-ui-util-1.6.11-commonMain-LLOBPg.klib
│ ├── org.jetbrains.compose.ui-ui-util-1.6.11-uikitMain-4Hpl6Q.klib
│ ├── org.jetbrains.kotlinx-atomicfu-0.23.2-commonMain-yBS35w.klib
│ ├── org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-yBS35w.klib
│ ├── co.touchlab-stately-iso-collections-2.0.6-commonMain-dUgCfw.klib
│ ├── io.github.pdvrieze.xmlutil-core-0.86.3-commonDomMain-nC7WJg.klib
│ ├── org.jetbrains.compose.runtime-runtime-1.6.11-jbMain-CVJWAg.klib
│ ├── org.jetbrains.compose.ui-ui-text-1.6.11-jsNativeMain-aUvkxg.klib
│ ├── org.jetbrains.compose.ui-ui-unit-1.6.11-jsNativeMain-vwDMdg.klib
│ ├── org.jetbrains.kotlin-kotlin-stdlib-2.0.0-commonMain-2bbUHA.klib
│ ├── androidx.lifecycle-lifecycle-viewmodel-2.8.3-commonMain-vv0pmw.klib
│ ├── androidx.lifecycle-lifecycle-viewmodel-2.8.3-darwinMain-4MgIRw.klib
│ ├── androidx.lifecycle-lifecycle-viewmodel-2.8.3-nativeMain-vv0pmw.klib
│ ├── androidx.lifecycle-lifecycle-viewmodel-2.8.3-nonJvmMain-vv0pmw.klib
│ ├── co.touchlab-stately-concurrency-2.0.6-nativeCommonMain-CAw19g.klib
│ ├── io.ktor-ktor-websocket-serialization-2.3.11-commonMain-8xBQEg.klib
│ ├── io.ktor-ktor-websocket-serialization-2.3.12-commonMain-8xBQEg.klib
│ ├── org.jetbrains.compose.runtime-runtime-1.6.11-commonMain-CVJWAg.klib
│ ├── org.jetbrains.compose.runtime-runtime-1.6.11-nativeMain-CVJWAg.klib
│ ├── org.jetbrains.compose.runtime-runtime-1.6.11-uikitMain-LSh9lw.klib
│ ├── org.jetbrains.compose.ui-ui-geometry-1.6.11-commonMain-zDj2GQ.klib
│ ├── org.jetbrains.compose.ui-ui-graphics-1.6.11-commonMain-jqr5iw.klib
│ ├── org.jetbrains.compose.ui-ui-graphics-1.6.11-nativeMain-M9RlEw.klib
│ ├── org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoMain-jqr5iw.klib
│ ├── org.jetbrains.compose.material-material-1.6.11-commonMain-tGo7Ag.klib
│ ├── org.jetbrains.compose.material-material-1.6.11-nativeMain-33WlwA.klib
│ ├── org.jetbrains.compose.material-material-1.6.11-skikoMain-tGo7Ag.klib
│ ├── org.jetbrains.compose.runtime-runtime-1.6.11-jsNativeMain-CVJWAg.klib
│ ├── org.jetbrains.compose.ui-ui-graphics-1.6.11-jsNativeMain-jqr5iw.klib
│ ├── io.github.pdvrieze.xmlutil-serialization-0.86.3-commonMain-6CN7gA.klib
│ ├── io.github.pdvrieze.xmlutil-serialization-0.86.3-nativeMain-6CN7gA.klib
│ ├── io.github.reactivecircus.cache4k-cache4k-0.13.0-commonMain-jqU5mQ.klib
│ ├── io.github.reactivecircus.cache4k-cache4k-0.13.0-nonJvmMain-jqU5mQ.klib
│ ├── org.jetbrains.compose.animation-animation-1.6.11-commonMain-5jNXZw.klib
│ ├── org.jetbrains.compose.animation-animation-1.6.11-nativeMain-tpXTFg.klib
│ ├── org.jetbrains.compose.animation-animation-core-1.6.11-jbMain-jNz1Aw.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-skikoMain-dXXsCQ.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-uikitMain-aASdXg.klib
│ ├── org.jetbrains.compose.material-material-1.6.11-jsNativeMain-tGo7Ag.klib
│ ├── org.jetbrains.kotlin-kotlin-test-2.0.0-annotationsCommonMain-24eTFQ.klib
│ ├── org.jetbrains.kotlin-kotlin-test-2.0.0-assertionsCommonMain-24eTFQ.klib
│ ├── org.jetbrains.compose.animation-animation-1.6.11-jsNativeMain-5jNXZw.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-commonMain-dXXsCQ.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-darwinMain-aASdXg.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-nativeMain-aASdXg.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-commonMain-UxhG-g.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeMain-UxhG-g.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-commonMain-XanZ2w.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeMain-XanZ2w.klib
│ ├── org.jetbrains.compose.animation-animation-core-1.6.11-commonMain-jNz1Aw.klib
│ ├── org.jetbrains.compose.animation-animation-core-1.6.11-uikitMain-2J6wbg.klib
│ ├── org.jetbrains.compose.foundation-foundation-1.6.11-jsNativeMain-dXXsCQ.klib
│ ├── org.jetbrains.compose.material-material-ripple-1.6.11-commonMain-8kHg7A.klib
│ ├── org.jetbrains.compose.material-material-ripple-1.6.11-nativeMain-zsMeyQ.klib
│ ├── org.jetbrains.compose.runtime-runtime-saveable-1.6.11-commonMain-pCPplQ.klib
│ ├── org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoExcludingWebMain-jqr5iw.klib
│ ├── org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-commonMain-oyg_tw.klib
│ ├── org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-nativeMain-oyg_tw.klib
│ ├── org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-commonMain-JDnEfA.klib
│ ├── org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-nativeMain-JDnEfA.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-commonMain-_oGBew.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-nonJvmMain-_oGBew.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-commonMain-Cd-IGw.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nativeMain-Cd-IGw.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nonJvmMain-Cd-IGw.klib
│ ├── org.jetbrains.compose.animation-animation-core-1.6.11-jsNativeMain-jNz1Aw.klib
│ ├── org.jetbrains.compose.collection-internal-collection-1.6.11-jbMain-hcu3Ug.klib
│ ├── org.jetbrains.compose.foundation-foundation-layout-1.6.11-skikoMain-89e7lw.klib
│ ├── org.jetbrains.compose.foundation-foundation-layout-1.6.11-uikitMain-BKR0pA.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-concurrentMain-UxhG-g.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-concurrentMain-XanZ2w.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-commonMain-ydSu5Q.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nativeMain-ydSu5Q.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nonJvmMain-ydSu5Q.klib
│ ├── org.jetbrains.compose.annotation-internal-annotation-1.6.11-commonMain-cNNKSA.klib
│ ├── org.jetbrains.compose.annotation-internal-annotation-1.6.11-nonJvmMain-cNNKSA.klib
│ ├── org.jetbrains.compose.collection-internal-collection-1.6.11-commonMain-hcu3Ug.klib
│ ├── org.jetbrains.compose.components-components-resources-1.6.11-iosMain-mlvQUA.klib
│ ├── org.jetbrains.compose.components-components-resources-1.6.11-skikoMain-44UCqg.klib
│ ├── org.jetbrains.compose.foundation-foundation-layout-1.6.11-commonMain-89e7lw.klib
│ ├── org.jetbrains.compose.foundation-foundation-layout-1.6.11-jsNativeMain-89e7lw.klib
│ ├── org.jetbrains.compose.material-material-icons-core-1.6.11-commonMain-XjyzjQ.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeDarwinMain-sy5nKg.klib
│ ├── org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeDarwinMain-sy5nKg.klib
│ ├── org.jetbrains.compose.collection-internal-collection-1.6.11-jsNativeMain-hcu3Ug.klib
│ ├── org.jetbrains.compose.components-components-resources-1.6.11-commonMain-44UCqg.klib
│ ├── org.jetbrains.compose.components-components-resources-1.6.11-nativeMain-mlvQUA.klib
│ ├── org.jetbrains.androidx.lifecycle-lifecycle-runtime-compose-2.8.0-commonMain-mvP4Vw.klib
│ ├── org.jetbrains.compose.components-components-resources-1.6.11-blockingMain-44UCqg.klib
│ └── org.jetbrains.compose.components-components-ui-tooling-preview-1.6.11-commonMain--i3iSw.klib
├── iosApp
├── Configuration
│ └── Config.xcconfig
├── iosApp
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── app-icon-1024.png
│ │ │ └── Contents.json
│ │ └── AccentColor.colorset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── iOSApp.swift
│ ├── ContentView.swift
│ └── Info.plist
└── iosApp.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── ahmedadelismail.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ └── ahmedadelismail.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── composeApp
├── src
│ ├── androidMain
│ │ ├── res
│ │ │ ├── values
│ │ │ │ └── strings.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
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── aismail
│ │ │ │ └── project
│ │ │ │ └── MainActivity.kt
│ │ └── AndroidManifest.xml
│ ├── commonMain
│ │ ├── kotlin
│ │ │ ├── shared
│ │ │ │ └── adapters
│ │ │ │ │ ├── Clearable.kt
│ │ │ │ │ └── StateHolder.kt
│ │ │ ├── login
│ │ │ │ ├── core
│ │ │ │ │ ├── User.kt
│ │ │ │ │ ├── ports
│ │ │ │ │ │ ├── LoginDataSourcePort.kt
│ │ │ │ │ │ └── LoginStatePort.kt
│ │ │ │ │ └── scenarios
│ │ │ │ │ │ └── LoginBusinessLogic.kt
│ │ │ │ ├── adapters
│ │ │ │ │ ├── Mapping.kt
│ │ │ │ │ ├── LoginState.kt
│ │ │ │ │ └── LoginDataSource.kt
│ │ │ │ └── ui
│ │ │ │ │ └── LoginScreen.kt
│ │ │ ├── navigation
│ │ │ │ ├── core
│ │ │ │ │ ├── ports
│ │ │ │ │ │ ├── NavigationDataSourcePort.kt
│ │ │ │ │ │ └── NavigationStatePort.kt
│ │ │ │ │ ├── Screens.kt
│ │ │ │ │ └── NavigationBusinessLogic.kt
│ │ │ │ ├── adapters
│ │ │ │ │ ├── NavigationDataSources.kt
│ │ │ │ │ └── NavigationState.kt
│ │ │ │ └── BackHandling.kt
│ │ │ ├── data
│ │ │ │ ├── models
│ │ │ │ │ ├── AllGithubRepositoriesData.kt
│ │ │ │ │ ├── OwnerData.kt
│ │ │ │ │ ├── UserData.kt
│ │ │ │ │ └── GithubRepositoryData.kt
│ │ │ │ ├── InMemoryCache.kt
│ │ │ │ ├── DataSources.kt
│ │ │ │ ├── DataSourcesImpl.kt
│ │ │ │ └── mocks
│ │ │ │ │ └── MockServerResponse.kt
│ │ │ ├── favorites
│ │ │ │ ├── core
│ │ │ │ │ ├── ports
│ │ │ │ │ │ ├── AllFavoritesDataSourcesPort.kt
│ │ │ │ │ │ ├── FavoriteDataSourcesPort.kt
│ │ │ │ │ │ ├── AllFavoritesStatePort.kt
│ │ │ │ │ │ └── FavoriteStatePort.kt
│ │ │ │ │ ├── entities
│ │ │ │ │ │ └── FavoriteRepository.kt
│ │ │ │ │ └── scenarios
│ │ │ │ │ │ ├── FavoritesBusinessLogic.kt
│ │ │ │ │ │ └── AllFavoritesBusinessLogic.kt
│ │ │ │ ├── adapters
│ │ │ │ │ ├── AllFavoritesDataSources.kt
│ │ │ │ │ ├── FavoriteDataSources.kt
│ │ │ │ │ ├── Mapping.kt
│ │ │ │ │ ├── FavoriteState.kt
│ │ │ │ │ └── AllFavoritesState.kt
│ │ │ │ └── ui
│ │ │ │ │ └── FavoritesScreen.kt
│ │ │ ├── home
│ │ │ │ ├── core
│ │ │ │ │ ├── ports
│ │ │ │ │ │ ├── HomeStatePort.kt
│ │ │ │ │ │ ├── HomeDataSourcesPort.kt
│ │ │ │ │ │ ├── GithubRepositoryDataSourcesPort.kt
│ │ │ │ │ │ └── GithubRepositoryStatePort.kt
│ │ │ │ │ ├── entities
│ │ │ │ │ │ └── GithubRepository.kt
│ │ │ │ │ └── scenarios
│ │ │ │ │ │ ├── GithubRepositoryBusinessLogic.kt
│ │ │ │ │ │ └── HomeBusinessLogic.kt
│ │ │ │ ├── adapters
│ │ │ │ │ ├── Mapping.kt
│ │ │ │ │ ├── HomeDataSources.kt
│ │ │ │ │ ├── HomeState.kt
│ │ │ │ │ ├── GithubRepositoryDataSources.kt
│ │ │ │ │ └── GithubRepositoryState.kt
│ │ │ │ └── ui
│ │ │ │ │ └── HomeScreen.kt
│ │ │ ├── splash
│ │ │ │ └── SplashScreen.kt
│ │ │ └── App.kt
│ │ └── composeResources
│ │ │ └── drawable
│ │ │ └── compose-multiplatform.xml
│ ├── iosMain
│ │ └── kotlin
│ │ │ └── MainViewController.kt
│ └── desktopMain
│ │ └── kotlin
│ │ └── main.kt
└── build.gradle.kts
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── libs.versions.toml
├── gradle.properties
├── server
├── src
│ └── main
│ │ ├── resources
│ │ └── logback.xml
│ │ └── kotlin
│ │ └── com
│ │ └── aismail
│ │ └── project
│ │ └── Application.kt
└── build.gradle.kts
├── .gitignore
├── settings.gradle.kts
├── README.md
├── gradlew.bat
└── gradlew
/shared/src/commonMain/kotlin/Constants.kt:
--------------------------------------------------------------------------------
1 | const val SERVER_PORT = 8080
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-iosMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-iosTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-appleMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-appleTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-nativeMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.shared-nativeTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/iosApp/Configuration/Config.xcconfig:
--------------------------------------------------------------------------------
1 | TEAM_ID=
2 | BUNDLE_ID=com.aismail.project.AIsmailProject
3 | APP_NAME=AIsmailProject
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AIsmailProject
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/shared/src/commonMain/kotlin/Platform.kt:
--------------------------------------------------------------------------------
1 | interface Platform {
2 | val name: String
3 | }
4 |
5 | expect fun getPlatform(): Platform
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/shared/adapters/Clearable.kt:
--------------------------------------------------------------------------------
1 | package shared.adapters
2 |
3 | interface Clearable {
4 | fun clear()
5 | }
--------------------------------------------------------------------------------
/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/core/User.kt:
--------------------------------------------------------------------------------
1 | package login.core
2 |
3 | data class User(
4 | val metadata: Any,
5 | val id: Long,
6 | val token: String,
7 | )
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/MainViewController.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.ui.window.ComposeUIViewController
2 |
3 | fun MainViewController() = ComposeUIViewController { App() }
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/shared/src/commonMain/kotlin/Greeting.kt:
--------------------------------------------------------------------------------
1 | class Greeting {
2 | private val platform = getPlatform()
3 |
4 | fun greet(): String {
5 | return "Hello, ${platform.name}!"
6 | }
7 | }
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/core/ports/NavigationDataSourcePort.kt:
--------------------------------------------------------------------------------
1 | package navigation.core.ports
2 |
3 | interface NavigationDataSourcePort {
4 | suspend fun isLoggedIn(): Boolean
5 | }
--------------------------------------------------------------------------------
/iosApp/iosApp/iOSApp.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | @main
4 | struct iOSApp: App {
5 | var body: some Scene {
6 | WindowGroup {
7 | ContentView()
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/shared/src/jvmMain/kotlin/Platform.jvm.kt:
--------------------------------------------------------------------------------
1 | class JVMPlatform: Platform {
2 | override val name: String = "Java ${System.getProperty("java.version")}"
3 | }
4 |
5 | actual fun getPlatform(): Platform = JVMPlatform()
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
--------------------------------------------------------------------------------
/shared/src/androidMain/kotlin/Platform.android.kt:
--------------------------------------------------------------------------------
1 | import android.os.Build
2 |
3 | class AndroidPlatform : Platform {
4 | override val name: String = "Android ${Build.VERSION.SDK_INT}"
5 | }
6 |
7 | actual fun getPlatform(): Platform = AndroidPlatform()
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-posixMain-VFYQnA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-posixMain-VFYQnA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-posixMain-3YsjwQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-posixMain-3YsjwQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.11-commonMain-QgEQ0Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.11-commonMain-QgEQ0Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.11-posixMain-QgEQ0Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.11-posixMain-QgEQ0Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.12-commonMain-W5sIeA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.12-commonMain-W5sIeA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.12-posixMain-W5sIeA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-http-2.3.12-posixMain-W5sIeA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-commonMain-VFYQnA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-commonMain-VFYQnA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-darwinMain-sbySvA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.11-darwinMain-sbySvA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-commonMain-3YsjwQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-commonMain-3YsjwQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-darwinMain-sbySvA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-io-2.3.12-darwinMain-sbySvA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-nixMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-nixMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-posixMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-posixMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-nixMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-nixMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-posixMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-posixMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-unixMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-unixMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-zlibMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-zlibMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-events-2.3.11-commonMain-_htHDg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-events-2.3.11-commonMain-_htHDg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-events-2.3.12-commonMain-Q6-xkw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-events-2.3.12-commonMain-Q6-xkw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-commonMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-commonMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-darwinMain-TE4abA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.11-darwinMain-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-commonMain-kEcFvw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-commonMain-kEcFvw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-darwinMain-TE4abA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-utils-2.3.12-darwinMain-TE4abA.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/core/Screens.kt:
--------------------------------------------------------------------------------
1 | package navigation.core
2 |
3 | sealed interface Screens {
4 | data object Splash : Screens
5 | data object Login : Screens
6 | data object Home : Screens
7 | data object Favorites : Screens
8 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-appleMain-BlIr1w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-appleMain-BlIr1w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-commonMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-commonMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-nativeMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-nativeMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-nonJvmMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-nonJvmMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.11-posixMain-8-9-_g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.11-posixMain-8-9-_g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.12-posixMain-8-9-_g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.12-posixMain-8-9-_g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-core-0.9.5-appleMain-aK6ixA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-core-0.9.5-appleMain-aK6ixA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-core-0.9.5-commonMain-WfPfow.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-core-0.9.5-commonMain-WfPfow.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-appleMain-fGtM2w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-appleMain-fGtM2w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-commonMain-oIJf-w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-commonMain-oIJf-w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-nonJvmMain-oIJf-w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/media.kamel-kamel-image-0.9.5-nonJvmMain-oIJf-w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-iosMain-1T2ZCw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-iosMain-1T2ZCw.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/models/AllGithubRepositoriesData.kt:
--------------------------------------------------------------------------------
1 | package data.models
2 |
3 | import GithubRepositoryData
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class AllGithubRepositoriesData(val data: List)
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-hashFunctions-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-hashFunctions-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.11-commonMain-FU-9lg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.11-commonMain-FU-9lg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.11-posixMain-FU-9lg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.11-posixMain-FU-9lg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.12-commonMain-FU-9lg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.12-commonMain-FU-9lg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.12-posixMain-FU-9lg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-core-2.3.12-posixMain-FU-9lg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.11-commonMain-8-9-_g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.11-commonMain-8-9-_g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.12-commonMain-8-9-_g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websockets-2.3.12-commonMain-8-9-_g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-commonMain-DbI_Jg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-commonMain-DbI_Jg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-darwinMain-1T2ZCw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-darwinMain-1T2ZCw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-nativeMain-DbI_Jg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-nativeMain-DbI_Jg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-common-2.0.6-commonMain-WJbBBA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-common-2.0.6-commonMain-WJbBBA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-isolate-2.0.6-commonMain-4Bzzzg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-isolate-2.0.6-commonMain-4Bzzzg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-strict-2.0.6-commonMain-0yIOhQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-strict-2.0.6-commonMain-0yIOhQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-darwin-2.3.11-darwinMain-CnRCQQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-darwin-2.3.11-darwinMain-CnRCQQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-darwin-2.3.12-darwinMain-CnRCQQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-client-darwin-2.3.12-darwinMain-CnRCQQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-serialization-2.3.11-commonMain-NxrIfg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-serialization-2.3.11-commonMain-NxrIfg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-serialization-2.3.12-commonMain-NxrIfg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-serialization-2.3.12-commonMain-NxrIfg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-commonMain-OrzU9w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-commonMain-OrzU9w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-darwinMain-OEwx0A.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-darwinMain-OEwx0A.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-nativeMain-OEwx0A.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-nativeMain-OEwx0A.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-skikoMain-OrzU9w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-skikoMain-OrzU9w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-uikitMain-OEwx0A.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-uikitMain-OEwx0A.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-nativeJsMain-DbI_Jg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.skiko-skiko-0.8.4-nativeJsMain-DbI_Jg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.annotation-annotation-1.8.0-commonMain-PJXh8Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.annotation-annotation-1.8.0-commonMain-PJXh8Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.annotation-annotation-1.8.0-nonJvmMain-PJXh8Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.annotation-annotation-1.8.0-nonJvmMain-PJXh8Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-jsNativeMain-OrzU9w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-1.6.11-jsNativeMain-OrzU9w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-jbMain-vwDMdg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-jbMain-vwDMdg.klib
--------------------------------------------------------------------------------
/shared/src/iosMain/kotlin/Platform.ios.kt:
--------------------------------------------------------------------------------
1 | import platform.UIKit.UIDevice
2 |
3 | class IOSPlatform: Platform {
4 | override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
5 | }
6 |
7 | actual fun getPlatform(): Platform = IOSPlatform()
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-common-2.0.6-nativeCommonMain-WJbBBA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-common-2.0.6-nativeCommonMain-WJbBBA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-commonMain-CAw19g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-commonMain-CAw19g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-darwinMain-oJtMMg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-darwinMain-oJtMMg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-isolate-2.0.6-nativeCommonMain-4Bzzzg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-isolate-2.0.6-nativeCommonMain-4Bzzzg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-strict-2.0.6-nativeCommonMain-0yIOhQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-strict-2.0.6-nativeCommonMain-0yIOhQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-systemFileSystemMain-DWVyIA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/com.squareup.okio-okio-3.9.0-systemFileSystemMain-DWVyIA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-commonMain-nC7WJg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-commonMain-nC7WJg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-nativeMain-nC7WJg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-nativeMain-nC7WJg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-commonMain-aUvkxg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-commonMain-aUvkxg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-darwinMain-DK5x5Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-darwinMain-DK5x5Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-nativeMain-DK5x5Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-nativeMain-DK5x5Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-skikoMain-aUvkxg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-skikoMain-aUvkxg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-oguluQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-oguluQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-commonMain-vwDMdg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-commonMain-vwDMdg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-util-1.6.11-commonMain-LLOBPg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-util-1.6.11-commonMain-LLOBPg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-util-1.6.11-uikitMain-4Hpl6Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-util-1.6.11-uikitMain-4Hpl6Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-commonMain-yBS35w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-commonMain-yBS35w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-yBS35w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-yBS35w.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/ports/AllFavoritesDataSourcesPort.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.ports
2 |
3 | import favorites.core.entities.FavoriteRepository
4 |
5 | interface AllFavoritesDataSourcesPort {
6 | suspend fun getAllFavorites(): List
7 | }
8 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/ports/FavoriteDataSourcesPort.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.ports
2 |
3 | import favorites.core.entities.FavoriteRepository
4 |
5 | interface FavoriteDataSourcesPort {
6 | suspend fun removeFromFavorites(favoriteRepository: FavoriteRepository)
7 | }
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/ahmedadelismail.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/ahmedadelismail.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-iso-collections-2.0.6-commonMain-dUgCfw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-iso-collections-2.0.6-commonMain-dUgCfw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-commonDomMain-nC7WJg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-core-0.86.3-commonDomMain-nC7WJg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-jbMain-CVJWAg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-jbMain-CVJWAg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-jsNativeMain-aUvkxg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-text-1.6.11-jsNativeMain-aUvkxg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-jsNativeMain-vwDMdg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-unit-1.6.11-jsNativeMain-vwDMdg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.0-commonMain-2bbUHA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-stdlib-2.0.0-commonMain-2bbUHA.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/ports/HomeStatePort.kt:
--------------------------------------------------------------------------------
1 | package home.core.ports
2 |
3 | interface HomeStatePort {
4 | val dataSourcePort: HomeDataSourcesPort
5 | var progress: Boolean
6 | val repositories: MutableList
7 | var error: Throwable?
8 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/core/NavigationBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package navigation.core
2 |
3 | import navigation.core.ports.NavigationStatePort
4 |
5 | suspend fun NavigationStatePort.initialize() {
6 | screen = if (dataSourcePort.isLoggedIn()) Screens.Home else Screens.Login
7 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-commonMain-vv0pmw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-commonMain-vv0pmw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-darwinMain-4MgIRw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-darwinMain-4MgIRw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-nativeMain-vv0pmw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-nativeMain-vv0pmw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-nonJvmMain-vv0pmw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/androidx.lifecycle-lifecycle-viewmodel-2.8.3-nonJvmMain-vv0pmw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-nativeCommonMain-CAw19g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/co.touchlab-stately-concurrency-2.0.6-nativeCommonMain-CAw19g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websocket-serialization-2.3.11-commonMain-8xBQEg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websocket-serialization-2.3.11-commonMain-8xBQEg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websocket-serialization-2.3.12-commonMain-8xBQEg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.ktor-ktor-websocket-serialization-2.3.12-commonMain-8xBQEg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-commonMain-CVJWAg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-commonMain-CVJWAg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-nativeMain-CVJWAg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-nativeMain-CVJWAg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-uikitMain-LSh9lw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-uikitMain-LSh9lw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-geometry-1.6.11-commonMain-zDj2GQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-geometry-1.6.11-commonMain-zDj2GQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-commonMain-jqr5iw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-commonMain-jqr5iw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-nativeMain-M9RlEw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-nativeMain-M9RlEw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoMain-jqr5iw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoMain-jqr5iw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-commonMain-tGo7Ag.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-commonMain-tGo7Ag.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-nativeMain-33WlwA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-nativeMain-33WlwA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-skikoMain-tGo7Ag.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-skikoMain-tGo7Ag.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-jsNativeMain-CVJWAg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-1.6.11-jsNativeMain-CVJWAg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-jsNativeMain-jqr5iw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-jsNativeMain-jqr5iw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-serialization-0.86.3-commonMain-6CN7gA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-serialization-0.86.3-commonMain-6CN7gA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-serialization-0.86.3-nativeMain-6CN7gA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.pdvrieze.xmlutil-serialization-0.86.3-nativeMain-6CN7gA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.reactivecircus.cache4k-cache4k-0.13.0-commonMain-jqU5mQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.reactivecircus.cache4k-cache4k-0.13.0-commonMain-jqU5mQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.reactivecircus.cache4k-cache4k-0.13.0-nonJvmMain-jqU5mQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/io.github.reactivecircus.cache4k-cache4k-0.13.0-nonJvmMain-jqU5mQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-commonMain-5jNXZw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-commonMain-5jNXZw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-nativeMain-tpXTFg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-nativeMain-tpXTFg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-jbMain-jNz1Aw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-jbMain-jNz1Aw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-skikoMain-dXXsCQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-skikoMain-dXXsCQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-uikitMain-aASdXg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-uikitMain-aASdXg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-jsNativeMain-tGo7Ag.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-1.6.11-jsNativeMain-tGo7Ag.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.0-annotationsCommonMain-24eTFQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.0-annotationsCommonMain-24eTFQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.0-assertionsCommonMain-24eTFQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlin-kotlin-test-2.0.0-assertionsCommonMain-24eTFQ.klib
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-jsNativeMain-5jNXZw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-1.6.11-jsNativeMain-5jNXZw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-commonMain-dXXsCQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-commonMain-dXXsCQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-darwinMain-aASdXg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-darwinMain-aASdXg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-nativeMain-aASdXg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-nativeMain-aASdXg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-commonMain-UxhG-g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-commonMain-UxhG-g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeMain-UxhG-g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeMain-UxhG-g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-commonMain-XanZ2w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-commonMain-XanZ2w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeMain-XanZ2w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeMain-XanZ2w.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/ports/AllFavoritesStatePort.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.ports
2 |
3 | interface AllFavoritesStatePort {
4 | val dataSources: AllFavoritesDataSourcesPort
5 | val favorites: MutableList
6 | var progress: Boolean
7 | var error: Throwable?
8 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/ports/HomeDataSourcesPort.kt:
--------------------------------------------------------------------------------
1 | package home.core.ports
2 |
3 | import home.core.entities.GithubRepository
4 |
5 | interface HomeDataSourcesPort {
6 | suspend fun getAllRepositories(): List
7 | suspend fun getAllFavorites(): List
8 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-commonMain-jNz1Aw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-commonMain-jNz1Aw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-uikitMain-2J6wbg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-uikitMain-2J6wbg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-jsNativeMain-dXXsCQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-1.6.11-jsNativeMain-dXXsCQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-ripple-1.6.11-commonMain-8kHg7A.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-ripple-1.6.11-commonMain-8kHg7A.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-ripple-1.6.11-nativeMain-zsMeyQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-ripple-1.6.11-nativeMain-zsMeyQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-saveable-1.6.11-commonMain-pCPplQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.runtime-runtime-saveable-1.6.11-commonMain-pCPplQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoExcludingWebMain-jqr5iw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.ui-ui-graphics-1.6.11-skikoExcludingWebMain-jqr5iw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-commonMain-oyg_tw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-commonMain-oyg_tw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-nativeMain-oyg_tw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-core-1.6.3-nativeMain-oyg_tw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-commonMain-JDnEfA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-commonMain-JDnEfA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-nativeMain-JDnEfA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-serialization-json-1.6.3-nativeMain-JDnEfA.klib
--------------------------------------------------------------------------------
/composeApp/src/desktopMain/kotlin/main.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.ui.window.Window
2 | import androidx.compose.ui.window.application
3 |
4 | fun main() = application {
5 | Window(
6 | onCloseRequest = ::exitApplication,
7 | title = "AIsmailProject",
8 | ) {
9 | App()
10 | }
11 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-commonMain-_oGBew.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-commonMain-_oGBew.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-nonJvmMain-_oGBew.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-common-2.8.0-nonJvmMain-_oGBew.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-commonMain-Cd-IGw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-commonMain-Cd-IGw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nativeMain-Cd-IGw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nativeMain-Cd-IGw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nonJvmMain-Cd-IGw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-2.8.0-nonJvmMain-Cd-IGw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-jsNativeMain-jNz1Aw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.animation-animation-core-1.6.11-jsNativeMain-jNz1Aw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-jbMain-hcu3Ug.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-jbMain-hcu3Ug.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-skikoMain-89e7lw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-skikoMain-89e7lw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-uikitMain-BKR0pA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-uikitMain-BKR0pA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-concurrentMain-UxhG-g.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-concurrentMain-UxhG-g.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-concurrentMain-XanZ2w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-concurrentMain-XanZ2w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-commonMain-ydSu5Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-commonMain-ydSu5Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nativeMain-ydSu5Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nativeMain-ydSu5Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nonJvmMain-ydSu5Q.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-viewmodel-2.8.0-nonJvmMain-ydSu5Q.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.annotation-internal-annotation-1.6.11-commonMain-cNNKSA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.annotation-internal-annotation-1.6.11-commonMain-cNNKSA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.annotation-internal-annotation-1.6.11-nonJvmMain-cNNKSA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.annotation-internal-annotation-1.6.11-nonJvmMain-cNNKSA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-commonMain-hcu3Ug.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-commonMain-hcu3Ug.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-iosMain-mlvQUA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-iosMain-mlvQUA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-skikoMain-44UCqg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-skikoMain-44UCqg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-commonMain-89e7lw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-commonMain-89e7lw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-jsNativeMain-89e7lw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.foundation-foundation-layout-1.6.11-jsNativeMain-89e7lw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-icons-core-1.6.11-commonMain-XjyzjQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.material-material-icons-core-1.6.11-commonMain-XjyzjQ.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeDarwinMain-sy5nKg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.0-nativeDarwinMain-sy5nKg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeDarwinMain-sy5nKg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.kotlinx-kotlinx-coroutines-core-1.8.1-nativeDarwinMain-sy5nKg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-jsNativeMain-hcu3Ug.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.collection-internal-collection-1.6.11-jsNativeMain-hcu3Ug.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-commonMain-44UCqg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-commonMain-44UCqg.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-nativeMain-mlvQUA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-nativeMain-mlvQUA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-compose-2.8.0-commonMain-mvP4Vw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.androidx.lifecycle-lifecycle-runtime-compose-2.8.0-commonMain-mvP4Vw.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-blockingMain-44UCqg.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-resources-1.6.11-blockingMain-44UCqg.klib
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/ports/GithubRepositoryDataSourcesPort.kt:
--------------------------------------------------------------------------------
1 | package home.core.ports
2 |
3 | import home.core.entities.GithubRepository
4 |
5 | interface GithubRepositoryDataSourcesPort {
6 | suspend fun addToFavorites(repository: GithubRepository)
7 | suspend fun removeFromFavorites(repository: GithubRepository)
8 | }
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "app-icon-1024.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-ui-tooling-preview-1.6.11-commonMain--i3iSw.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedMetadataLibraries/org.jetbrains.compose.components-components-ui-tooling-preview-1.6.11-commonMain--i3iSw.klib
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/core/ports/NavigationStatePort.kt:
--------------------------------------------------------------------------------
1 | package navigation.core.ports
2 |
3 | import navigation.core.Screens
4 | import shared.adapters.StateHolder
5 |
6 | interface NavigationStatePort {
7 | val dataSourcePort: NavigationDataSourcePort
8 | var screen: Screens
9 | var state: StateHolder<*>?
10 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/entities/FavoriteRepository.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.entities
2 |
3 | data class FavoriteRepository(
4 | val metadata: Any,
5 | val id: Long,
6 | val name: String? = null,
7 | val ownerName: String? = null,
8 | val avatarUrl: String? = null,
9 | val stargazersCount: Int? = null,
10 | )
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.11-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.11-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/ports/FavoriteStatePort.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.ports
2 |
3 | import favorites.core.entities.FavoriteRepository
4 |
5 | interface FavoriteStatePort {
6 | val dataSources: FavoriteDataSourcesPort
7 | val favoriteRepository: FavoriteRepository
8 | var progress: Boolean
9 | var error: Throwable?
10 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.code.style=official
2 |
3 | #Gradle
4 | org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
5 |
6 | #Android
7 | android.nonTransitiveRClass=true
8 | android.useAndroidX=true
9 |
10 | #Kotlin Multiplatform
11 | kotlin.mpp.enableCInteropCommonization=true
12 |
13 | #Ktor
14 | io.ktor.development=true
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/scenarios/FavoritesBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.scenarios
2 |
3 | import favorites.core.ports.FavoriteStatePort
4 |
5 | suspend fun FavoriteStatePort.removeFromFavorite() {
6 | progress = true
7 | runCatching { dataSources.removeFromFavorites(favoriteRepository) }
8 | .onFailure { error = it }
9 | progress = false
10 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/ports/GithubRepositoryStatePort.kt:
--------------------------------------------------------------------------------
1 | package home.core.ports
2 |
3 | import home.core.entities.GithubRepository
4 |
5 | interface GithubRepositoryStatePort {
6 | val dataSourcePort: GithubRepositoryDataSourcesPort
7 | val repository: GithubRepository
8 | var isFavorite: Boolean
9 | var progress: Boolean
10 | var error: Throwable?
11 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/KMM-Compose-2024/HEAD/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/models/OwnerData.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.serialization.SerialName
2 | import kotlinx.serialization.Serializable
3 |
4 | @Serializable
5 | data class OwnerData(
6 | @SerialName("id") val id: Long? = null,
7 | @SerialName("private") val isPrivate: Boolean? = null,
8 | @SerialName("name") val name: String? = null,
9 | @SerialName("avatar_url") val avatarUrl: String? = null
10 | )
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/core/ports/LoginDataSourcePort.kt:
--------------------------------------------------------------------------------
1 | package login.core.ports
2 |
3 | import login.core.User
4 |
5 | interface LoginDataSourcePort {
6 | suspend fun getUsernameValidation(): List<(String?) -> Boolean>
7 | suspend fun getPasswordValidations(): List<(String?) -> Boolean>
8 | suspend fun login(username: String?, password: String?): User
9 | suspend fun saveUser(user: User)
10 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/adapters/NavigationDataSources.kt:
--------------------------------------------------------------------------------
1 | package navigation.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import navigation.core.ports.NavigationDataSourcePort
6 |
7 | class NavigationDataSources(
8 | private val dataSources: DataSources = DataSourcesImpl
9 | ) : NavigationDataSourcePort {
10 | override suspend fun isLoggedIn(): Boolean = dataSources.isLoggedIn()
11 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/core/ports/LoginStatePort.kt:
--------------------------------------------------------------------------------
1 | package login.core.ports
2 |
3 | interface LoginStatePort {
4 | val dataSourcePort: LoginDataSourcePort
5 | var progress: Boolean
6 | var userName: String?
7 | var password: String?
8 | var result: Result?
9 |
10 | sealed interface Result {
11 | data object Success : Result
12 | data class Error(val error: Throwable) : Result
13 | }
14 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/adapters/Mapping.kt:
--------------------------------------------------------------------------------
1 | package login.adapters
2 |
3 | import data.models.UserData
4 | import login.core.User
5 |
6 | fun createUser(userData: UserData) = User(
7 | metadata = userData,
8 | id = userData.id ?: throw IllegalArgumentException("User id is required"),
9 | token = userData.token ?: throw IllegalArgumentException("User token is required"),
10 | )
11 |
12 | val User.userData: UserData
13 | get() = metadata as UserData
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/shared/adapters/StateHolder.kt:
--------------------------------------------------------------------------------
1 | package shared.adapters
2 |
3 | import data.cache
4 |
5 | class StateHolder(val name: String, private val initialState: T) : Clearable {
6 | private var state by cache(name)
7 |
8 | fun state(): T = state ?: initialState.also { state = it }
9 |
10 | override fun clear() {
11 | val finalState = state
12 | if (finalState is Clearable) finalState.clear()
13 | state = null
14 | }
15 | }
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/xcuserdata/ahmedadelismail.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | iosApp.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/models/UserData.kt:
--------------------------------------------------------------------------------
1 | package data.models
2 |
3 | import kotlinx.serialization.SerialName
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class UserData(
8 | @SerialName("id") val id: Long? = null,
9 | @SerialName("token") val token: String? = null,
10 | @SerialName("name") val name: String? = null,
11 | @SerialName("email") val email: String? = null,
12 | @SerialName("avatar_url") val avatarUrl: String? = null,
13 | )
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/entities/GithubRepository.kt:
--------------------------------------------------------------------------------
1 | package home.core.entities
2 |
3 | data class GithubRepository(
4 | /**
5 | * holds the pojo received from data source to be used later on when
6 | * dealing with data sources layer in other operations
7 | */
8 | val metadata: Any,
9 | val id: Long,
10 | val name: String? = null,
11 | val ownerName: String? = null,
12 | val avatarUrl: String? = null,
13 | val stargazersCount: Int? = null,
14 | )
--------------------------------------------------------------------------------
/server/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/BackHandling.kt:
--------------------------------------------------------------------------------
1 | package navigation
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import kotlin.properties.Delegates
7 |
8 | class Provider(val value: T) {}
9 |
10 | class OnBackPressedChannel {
11 | var isBackPressActive by mutableStateOf(false)
12 | var onBackPressed: (() -> Unit)? by Delegates.observable(null) { _, _, value ->
13 | isBackPressActive = value != null
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle files
2 | .gradle/
3 | build/
4 |
5 | # Local configuration file (sdk path, etc)
6 | local.properties
7 |
8 | # Log/OS Files
9 | *.log
10 |
11 | # Android Studio generated files and folders
12 | captures/
13 | .externalNativeBuild/
14 | .cxx/
15 | *.apk
16 | output.json
17 |
18 | # IntelliJ
19 | *.iml
20 | .idea/
21 | misc.xml
22 | deploymentTargetDropDown.xml
23 | render.experimental.xml
24 |
25 | # Keystore files
26 | *.jks
27 | *.keystore
28 |
29 | # Google Services (e.g. APIs or Firebase)
30 | google-services.json
31 |
32 | # Android Profiling
33 | *.hprof
34 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/adapters/AllFavoritesDataSources.kt:
--------------------------------------------------------------------------------
1 | package favorites.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import favorites.core.entities.FavoriteRepository
6 | import favorites.core.ports.AllFavoritesDataSourcesPort
7 |
8 | class AllFavoritesDataSources(
9 | private val dataSources: DataSources = DataSourcesImpl
10 | ) : AllFavoritesDataSourcesPort {
11 | override suspend fun getAllFavorites(): List {
12 | return dataSources.getAllFavorites().map { createFavoriteRepository(it) }
13 | }
14 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/adapters/FavoriteDataSources.kt:
--------------------------------------------------------------------------------
1 | package favorites.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import favorites.core.entities.FavoriteRepository
6 | import favorites.core.ports.FavoriteDataSourcesPort
7 |
8 | class FavoriteDataSources(
9 | private val dataSources: DataSources = DataSourcesImpl
10 | ) : FavoriteDataSourcesPort {
11 | override suspend fun removeFromFavorites(favoriteRepository: FavoriteRepository) {
12 | return dataSources.removeFromFavorites(favoriteRepository.githubRepositoryData)
13 | }
14 | }
--------------------------------------------------------------------------------
/iosApp/iosApp/ContentView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SwiftUI
3 | import ComposeApp
4 |
5 | struct ComposeView: UIViewControllerRepresentable {
6 | func makeUIViewController(context: Context) -> UIViewController {
7 | MainViewControllerKt.MainViewController()
8 | }
9 |
10 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
11 | }
12 |
13 | struct ContentView: View {
14 | var body: some View {
15 | ComposeView()
16 | .ignoresSafeArea(.keyboard) // Compose has own keyboard handler
17 | }
18 | }
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/adapters/Mapping.kt:
--------------------------------------------------------------------------------
1 | package home.adapters
2 |
3 | import GithubRepositoryData
4 | import home.core.entities.GithubRepository
5 |
6 | fun createGithubRepository(data: GithubRepositoryData) = GithubRepository(
7 | metadata = data,
8 | id = data.id ?: throw IllegalArgumentException("Missing GithubRepositoryData id"),
9 | name = data.name,
10 | ownerName = data.owner?.name,
11 | avatarUrl = data.owner?.avatarUrl,
12 | stargazersCount = data.stargazersCount,
13 | )
14 |
15 | val GithubRepository.githubRepositoryData: GithubRepositoryData
16 | get() = metadata as GithubRepositoryData
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/models/GithubRepositoryData.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.serialization.SerialName
2 | import kotlinx.serialization.Serializable
3 |
4 | @Serializable
5 | data class GithubRepositoryData(
6 | @SerialName("id") val id: Long? = null,
7 | @SerialName("private") val isPrivate: Boolean? = null,
8 | @SerialName("name") val name: String? = null,
9 | @SerialName("description") val description: String? = null,
10 | @SerialName("stargazers_count") val stargazersCount: Int? = null,
11 | @SerialName("languages_url") val languagesUrl: String? = null,
12 | @SerialName("owner") val owner: OwnerData? = null
13 | )
--------------------------------------------------------------------------------
/server/src/main/kotlin/com/aismail/project/Application.kt:
--------------------------------------------------------------------------------
1 | package com.aismail.project
2 |
3 | import Greeting
4 | import SERVER_PORT
5 | import io.ktor.server.application.*
6 | import io.ktor.server.engine.*
7 | import io.ktor.server.netty.*
8 | import io.ktor.server.response.*
9 | import io.ktor.server.routing.*
10 |
11 | fun main() {
12 | embeddedServer(Netty, port = SERVER_PORT, host = "0.0.0.0", module = Application::module)
13 | .start(wait = true)
14 | }
15 |
16 | fun Application.module() {
17 | routing {
18 | get("/") {
19 | call.respondText("Ktor: ${Greeting().greet()}")
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/adapters/Mapping.kt:
--------------------------------------------------------------------------------
1 | package favorites.adapters
2 |
3 | import GithubRepositoryData
4 | import favorites.core.entities.FavoriteRepository
5 |
6 | internal fun createFavoriteRepository(data: GithubRepositoryData) = FavoriteRepository(
7 | metadata = data,
8 | id = data.id ?: throw IllegalArgumentException("Missing GithubRepositoryData id"),
9 | name = data.name,
10 | ownerName = data.owner?.name,
11 | avatarUrl = data.owner?.avatarUrl,
12 | stargazersCount = data.stargazersCount,
13 | )
14 |
15 | val FavoriteRepository.githubRepositoryData: GithubRepositoryData
16 | get() = metadata as GithubRepositoryData
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/core/scenarios/AllFavoritesBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package favorites.core.scenarios
2 |
3 | import favorites.core.entities.FavoriteRepository
4 | import favorites.core.ports.AllFavoritesStatePort
5 | import favorites.core.ports.FavoriteStatePort
6 |
7 |
8 | suspend fun AllFavoritesStatePort.listAll(
9 | favoritePortFactory: (FavoriteRepository) -> FavoriteStatePort
10 | ) {
11 | progress = true
12 | runCatching { dataSources.getAllFavorites() }
13 | .mapCatching { it.map(favoritePortFactory) }
14 | .onFailure { error = it }
15 | .onSuccess { favorites.clear(); favorites.addAll(it) }
16 | progress = false
17 | }
--------------------------------------------------------------------------------
/server/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.kotlinJvm)
3 | alias(libs.plugins.ktor)
4 | application
5 | }
6 |
7 | group = "com.aismail.project"
8 | version = "1.0.0"
9 | application {
10 | mainClass.set("com.aismail.project.ApplicationKt")
11 | applicationDefaultJvmArgs = listOf("-Dio.ktor.development=${extra["io.ktor.development"] ?: "false"}")
12 | }
13 |
14 | dependencies {
15 | implementation(projects.shared)
16 | implementation(libs.logback)
17 | implementation(libs.ktor.server.core)
18 | implementation(libs.ktor.server.netty)
19 | testImplementation(libs.ktor.server.tests)
20 | testImplementation(libs.kotlin.test.junit)
21 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/adapters/FavoriteState.kt:
--------------------------------------------------------------------------------
1 | package favorites.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import favorites.core.entities.FavoriteRepository
7 | import favorites.core.ports.FavoriteDataSourcesPort
8 | import favorites.core.ports.FavoriteStatePort
9 |
10 | class FavoriteState(
11 | override val favoriteRepository: FavoriteRepository,
12 | override val dataSources: FavoriteDataSourcesPort = FavoriteDataSources()
13 | ) : FavoriteStatePort {
14 | override var progress by mutableStateOf(false)
15 | override var error: Throwable? by mutableStateOf(null)
16 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/navigation/adapters/NavigationState.kt:
--------------------------------------------------------------------------------
1 | package navigation.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import navigation.core.Screens
7 | import navigation.core.ports.NavigationDataSourcePort
8 | import navigation.core.ports.NavigationStatePort
9 | import shared.adapters.StateHolder
10 |
11 | class NavigationState(
12 | override val dataSourcePort: NavigationDataSourcePort = NavigationDataSources(),
13 | ) : NavigationStatePort {
14 | override var screen by mutableStateOf(Screens.Splash)
15 | override var state by mutableStateOf?>(null)
16 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/adapters/HomeDataSources.kt:
--------------------------------------------------------------------------------
1 | package home.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import home.core.entities.GithubRepository
6 | import home.core.ports.HomeDataSourcesPort
7 |
8 | class HomeDataSources(
9 | private val dataSources: DataSources = DataSourcesImpl
10 | ) : HomeDataSourcesPort {
11 | override suspend fun getAllRepositories(): List {
12 | return dataSources.getAllGithubRepositories().data.map { createGithubRepository(it) }
13 | }
14 |
15 | override suspend fun getAllFavorites(): List {
16 | return dataSources.getAllFavorites().map { createGithubRepository(it) }
17 | }
18 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/adapters/HomeState.kt:
--------------------------------------------------------------------------------
1 | package home.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateListOf
5 | import androidx.compose.runtime.mutableStateOf
6 | import androidx.compose.runtime.setValue
7 | import home.core.ports.GithubRepositoryStatePort
8 | import home.core.ports.HomeDataSourcesPort
9 | import home.core.ports.HomeStatePort
10 |
11 | class HomeState(
12 | override val dataSourcePort: HomeDataSourcesPort = HomeDataSources()
13 | ) : HomeStatePort {
14 | override var progress by mutableStateOf(false)
15 | override var error by mutableStateOf(null)
16 | override val repositories = mutableStateListOf()
17 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/adapters/GithubRepositoryDataSources.kt:
--------------------------------------------------------------------------------
1 | package home.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import home.core.entities.GithubRepository
6 | import home.core.ports.GithubRepositoryDataSourcesPort
7 |
8 | class GithubRepositoryDataSources(
9 | private val dataSources: DataSources = DataSourcesImpl
10 | ) : GithubRepositoryDataSourcesPort {
11 |
12 | override suspend fun addToFavorites(repository: GithubRepository) {
13 | dataSources.addToFavorites(repository.githubRepositoryData)
14 | }
15 |
16 | override suspend fun removeFromFavorites(repository: GithubRepository) {
17 | dataSources.removeFromFavorites(repository.githubRepositoryData)
18 | }
19 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/adapters/LoginState.kt:
--------------------------------------------------------------------------------
1 | package login.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import androidx.lifecycle.ViewModel
7 | import login.core.ports.LoginDataSourcePort
8 | import login.core.ports.LoginStatePort
9 |
10 | class LoginState(
11 | override val dataSourcePort: LoginDataSourcePort = LoginDataSource()
12 | ) : ViewModel(), LoginStatePort {
13 | override var userName by mutableStateOf(null)
14 | override var password by mutableStateOf(null)
15 | override var progress by mutableStateOf(false)
16 | override var result by mutableStateOf(null)
17 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/adapters/LoginDataSource.kt:
--------------------------------------------------------------------------------
1 | package login.adapters
2 |
3 | import data.DataSources
4 | import data.DataSourcesImpl
5 | import login.core.User
6 | import login.core.ports.LoginDataSourcePort
7 |
8 | class LoginDataSource(
9 | private val dataSources: DataSources = DataSourcesImpl
10 | ) : LoginDataSourcePort {
11 | override suspend fun getUsernameValidation() = dataSources.getUsernameValidation()
12 | override suspend fun getPasswordValidations() = dataSources.getPasswordValidations()
13 | override suspend fun saveUser(user: User) = dataSources.saveUser(user.userData)
14 | override suspend fun login(username: String?, password: String?) =
15 | createUser(dataSources.postLogin(username, password))
16 | }
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-appleMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-appleTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-iosMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-iosTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-nativeMain.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/.composeApp-nativeTest.cinteropLibraries:
--------------------------------------------------------------------------------
1 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.kotlinx-atomicfu-0.23.2-nativeMain-cinterop/org.jetbrains.kotlinx_atomicfu-cinterop-interop-yBS35w.klib
2 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/org.jetbrains.compose.ui-ui-uikit-1.6.11-uikitMain-cinterop/org.jetbrains.compose.ui_ui-uikit-cinterop-utils-oguluQ.klib
3 | /Users/ahmedadelismail/AndroidStudioProjects/KMM-Compose-2024/.kotlin/metadata/kotlinTransformedCInteropMetadataLibraries/io.ktor-ktor-utils-2.3.12-iosMain-cinterop/io.ktor_ktor-utils-cinterop-threadUtils-TE4abA.klib
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/com/aismail/project/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.aismail.project
2 |
3 | import App
4 | import android.os.Bundle
5 | import androidx.activity.ComponentActivity
6 | import androidx.activity.compose.BackHandler
7 | import androidx.activity.compose.setContent
8 | import navigation.OnBackPressedChannel
9 |
10 | class MainActivity : ComponentActivity() {
11 |
12 | private lateinit var backPressedChannel: OnBackPressedChannel
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContent {
17 |
18 | App { backPressedChannel = it.value }
19 |
20 | BackHandler(backPressedChannel.isBackPressActive) {
21 | backPressedChannel.onBackPressed?.invoke()
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/adapters/GithubRepositoryState.kt:
--------------------------------------------------------------------------------
1 | package home.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import home.core.entities.GithubRepository
7 | import home.core.ports.GithubRepositoryDataSourcesPort
8 | import home.core.ports.GithubRepositoryStatePort
9 |
10 | class GithubRepositoryState(
11 | githubRepository: GithubRepository,
12 | override val dataSourcePort: GithubRepositoryDataSourcesPort = GithubRepositoryDataSources()
13 | ) : GithubRepositoryStatePort {
14 | override var isFavorite by mutableStateOf(false)
15 | override val repository by mutableStateOf(githubRepository)
16 | override var progress by mutableStateOf(false)
17 | override var error by mutableStateOf(null)
18 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/InMemoryCache.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("UNCHECKED_CAST")
2 |
3 | package data
4 |
5 | import androidx.annotation.VisibleForTesting
6 | import kotlin.properties.ReadWriteProperty
7 | import kotlin.reflect.KProperty
8 |
9 | object InMemoryCache {
10 | val cache = mutableMapOf()
11 |
12 | @VisibleForTesting
13 | fun clear() {
14 | cache.clear()
15 | }
16 | }
17 |
18 | fun cache(key: String, onChanged: ((T?) -> Unit)? = null) =
19 | object : ReadWriteProperty {
20 | override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
21 | return InMemoryCache.cache[key] as? T?
22 | }
23 |
24 | override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
25 | InMemoryCache.cache[key] = value
26 | onChanged?.invoke(value)
27 | }
28 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/adapters/AllFavoritesState.kt:
--------------------------------------------------------------------------------
1 | package favorites.adapters
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateListOf
5 | import androidx.compose.runtime.mutableStateOf
6 | import androidx.compose.runtime.setValue
7 | import favorites.core.ports.AllFavoritesDataSourcesPort
8 | import favorites.core.ports.AllFavoritesStatePort
9 | import favorites.core.ports.FavoriteStatePort
10 | import shared.adapters.Clearable
11 |
12 | class AllFavoritesState(
13 | override val dataSources: AllFavoritesDataSourcesPort = AllFavoritesDataSources()
14 | ) : AllFavoritesStatePort, Clearable {
15 | override var favorites = mutableStateListOf()
16 | override var progress by mutableStateOf(false)
17 | override var error by mutableStateOf(null)
18 | override fun clear() {
19 | favorites.clear()
20 | }
21 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "AIsmailProject"
2 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
3 |
4 | pluginManagement {
5 | repositories {
6 | google {
7 | mavenContent {
8 | includeGroupAndSubgroups("androidx")
9 | includeGroupAndSubgroups("com.android")
10 | includeGroupAndSubgroups("com.google")
11 | }
12 | }
13 | mavenCentral()
14 | gradlePluginPortal()
15 | }
16 | }
17 |
18 | dependencyResolutionManagement {
19 | repositories {
20 | google {
21 | mavenContent {
22 | includeGroupAndSubgroups("androidx")
23 | includeGroupAndSubgroups("com.android")
24 | includeGroupAndSubgroups("com.google")
25 | }
26 | }
27 | mavenCentral()
28 | }
29 | }
30 |
31 | include(":composeApp")
32 | include(":server")
33 | include(":shared")
--------------------------------------------------------------------------------
/shared/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | alias(libs.plugins.kotlinMultiplatform)
6 | alias(libs.plugins.androidLibrary)
7 | }
8 |
9 | kotlin {
10 | androidTarget {
11 | @OptIn(ExperimentalKotlinGradlePluginApi::class)
12 | compilerOptions {
13 | jvmTarget.set(JvmTarget.JVM_11)
14 | }
15 | }
16 |
17 | iosX64()
18 | iosArm64()
19 | iosSimulatorArm64()
20 |
21 | jvm()
22 |
23 | sourceSets {
24 | commonMain.dependencies {
25 | // put your Multiplatform dependencies here
26 | }
27 | }
28 | }
29 |
30 | android {
31 | namespace = "com.aismail.project.shared"
32 | compileSdk = libs.versions.android.compileSdk.get().toInt()
33 | compileOptions {
34 | sourceCompatibility = JavaVersion.VERSION_11
35 | targetCompatibility = JavaVersion.VERSION_11
36 | }
37 | defaultConfig {
38 | minSdk = libs.versions.android.minSdk.get().toInt()
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/scenarios/GithubRepositoryBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package home.core.scenarios
2 |
3 | import home.core.entities.GithubRepository
4 | import home.core.ports.GithubRepositoryStatePort
5 |
6 |
7 | suspend fun GithubRepositoryStatePort.initialize(favorites: List): GithubRepositoryStatePort {
8 | error = null
9 | progress = true
10 | isFavorite = favorites.any { it.id == repository.id }
11 | progress = false
12 | return this
13 | }
14 |
15 | suspend fun GithubRepositoryStatePort.addToFavorites() {
16 | if (progress) return
17 | error = null
18 | progress = true
19 | runCatching { dataSourcePort.addToFavorites(repository) }
20 | .onSuccess { isFavorite = true }
21 | .onFailure { error = it }
22 | progress = false
23 | }
24 |
25 | suspend fun GithubRepositoryStatePort.removeFromFavorites() {
26 | if (progress) return
27 | error = null
28 | progress = true
29 | runCatching { dataSourcePort.removeFromFavorites(repository) }
30 | .onSuccess { isFavorite = false }
31 | .onFailure { error = it }
32 | progress = false
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/splash/SplashScreen.kt:
--------------------------------------------------------------------------------
1 | package splash
2 |
3 | import Greeting
4 | import aismailproject.composeapp.generated.resources.Res
5 | import aismailproject.composeapp.generated.resources.compose_multiplatform
6 | import androidx.compose.animation.AnimatedVisibility
7 | import androidx.compose.foundation.Image
8 | import androidx.compose.foundation.layout.Column
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.material.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.remember
13 | import androidx.compose.ui.Alignment
14 | import androidx.compose.ui.Modifier
15 | import org.jetbrains.compose.resources.painterResource
16 |
17 | @Composable
18 | fun SplashScreen() {
19 | Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
20 | AnimatedVisibility(true) {
21 | val greeting = remember { Greeting().greet() }
22 | Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
23 | Image(painterResource(Res.drawable.compose_multiplatform), null)
24 | Text("Compose: $greeting")
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/core/scenarios/LoginBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package login.core.scenarios
2 |
3 | import login.core.ports.LoginStatePort
4 | import login.core.ports.LoginStatePort.Result.Error
5 | import login.core.ports.LoginStatePort.Result.Success
6 |
7 | suspend fun LoginStatePort.login() {
8 | progress = true
9 | validate(userName, password)
10 | .mapCatching { dataSourcePort.login(it.first, it.second) }
11 | .mapCatching { dataSourcePort.saveUser(it) }
12 | .onSuccess { result = Success }
13 | .onFailure { result = Error(it) }
14 | progress = false
15 | }
16 |
17 | private suspend fun LoginStatePort.validate(
18 | userName: String?,
19 | password: String?
20 | ) = runCatching {
21 | if (!dataSourcePort.getUsernameValidation().all { validation -> validation(userName) }) {
22 | throw InvalidUsernameException
23 | }
24 | if (!dataSourcePort.getPasswordValidations().all { validation -> validation(password) }) {
25 | throw InvalidPasswordException
26 | }
27 | userName to password
28 | }
29 |
30 | // in real life, more errors to be handled, like generic and network errors
31 | object InvalidUsernameException : Exception()
32 | object InvalidPasswordException : Exception()
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/DataSources.kt:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import GithubRepositoryData
4 | import androidx.compose.runtime.State
5 | import data.models.AllGithubRepositoriesData
6 | import data.models.UserData
7 |
8 | /**
9 | * an interface to be implemented in unit tests and by different actual classes if required
10 | *
11 | * all methods are optional to make unit testing easier
12 | */
13 | interface DataSources {
14 | suspend fun isLoggedIn(): Boolean = throw NotImplementedError()
15 | suspend fun getUsernameValidation(): List<(String?) -> Boolean> = throw NotImplementedError()
16 | suspend fun getPasswordValidations(): List<(String?) -> Boolean> = throw NotImplementedError()
17 | suspend fun postLogin(username: String?, password: String?): UserData =
18 | throw NotImplementedError()
19 |
20 | suspend fun saveUser(userData: UserData): Unit = throw NotImplementedError()
21 | suspend fun getAllGithubRepositories(): AllGithubRepositoriesData = throw NotImplementedError()
22 | suspend fun addToFavorites(repository: GithubRepositoryData): Unit = throw NotImplementedError()
23 | suspend fun removeFromFavorites(repository: GithubRepositoryData): Unit =
24 | throw NotImplementedError()
25 |
26 | suspend fun getAllFavorites(): List = throw NotImplementedError()
27 | fun observeOnFavoritesSize(): State = throw NotImplementedError()
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/core/scenarios/HomeBusinessLogic.kt:
--------------------------------------------------------------------------------
1 | package home.core.scenarios
2 |
3 | import home.core.entities.GithubRepository
4 | import home.core.ports.GithubRepositoryStatePort
5 | import home.core.ports.HomeStatePort
6 | import kotlinx.coroutines.CoroutineDispatcher
7 | import kotlinx.coroutines.async
8 | import kotlinx.coroutines.coroutineScope
9 |
10 | suspend fun HomeStatePort.listAll(
11 | ioDispatcher: CoroutineDispatcher,
12 | repositoryPortFactory: (GithubRepository) -> GithubRepositoryStatePort
13 | ) = coroutineScope {
14 | error = null
15 | progress = true
16 | val repositories = async(ioDispatcher) { fetchAllRepositories() }
17 | val favorites = async(ioDispatcher) { fetchAllFavorites() }
18 | merge(repositories.await(), favorites.await(), repositoryPortFactory)
19 | }
20 |
21 | private suspend fun HomeStatePort.fetchAllRepositories() =
22 | runCatching { dataSourcePort.getAllRepositories() }
23 | .onFailure { error = it }
24 | .getOrDefault(listOf())
25 |
26 |
27 | private suspend fun HomeStatePort.fetchAllFavorites() =
28 | runCatching { dataSourcePort.getAllFavorites() }
29 | .onFailure { error = it }
30 | .getOrDefault(listOf())
31 |
32 |
33 | private suspend fun HomeStatePort.merge(
34 | fetchedRepositories: List,
35 | favorites: List,
36 | repositoryPortFactory: (GithubRepository) -> GithubRepositoryStatePort
37 | ) {
38 | if (fetchedRepositories.isNotEmpty()) {
39 | repositories.addAll(fetchedRepositories.map { repositoryPortFactory(it).initialize(favorites) })
40 | }
41 | progress = false
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | CADisableMinimumFrameDurationOnPhone
24 |
25 | UIApplicationSceneManifest
26 |
27 | UIApplicationSupportsMultipleScenes
28 |
29 |
30 | UILaunchScreen
31 |
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a POC project to clarify how Hexagonal architecture combined with DDD can acheive more than 80% of the code to be KMM & Compose while platforms required code will be limited to edge cases and depending on there libraries for data-sources related code
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | =========
10 |
11 | This is a Kotlin Multiplatform project targeting Android, iOS, Desktop, Server.
12 |
13 | * `/composeApp` is for code that will be shared across your Compose Multiplatform applications.
14 | It contains several subfolders:
15 | - `commonMain` is for code that’s common for all targets.
16 | - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name.
17 | For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app,
18 | `iosMain` would be the right folder for such calls.
19 |
20 | * `/iosApp` contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform,
21 | you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.
22 |
23 | * `/server` is for the Ktor server application.
24 |
25 | * `/shared` is for the code that will be shared between all targets in the project.
26 | The most important subfolder is `commonMain`. If preferred, you can add code to the platform-specific folders here too.
27 |
28 | Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)…
29 |
30 |
31 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | agp = "8.5.0-rc01"
3 | android-compileSdk = "34"
4 | android-minSdk = "24"
5 | android-targetSdk = "34"
6 | androidx-activityCompose = "1.9.0"
7 | androidx-appcompat = "1.7.0"
8 | androidx-constraintlayout = "2.1.4"
9 | androidx-core-ktx = "1.13.1"
10 | androidx-espresso-core = "3.6.0"
11 | androidx-material = "1.12.0"
12 | androidx-test-junit = "1.2.0"
13 | compose-plugin = "1.6.11"
14 | junit = "4.13.2"
15 | kamelImage = "0.9.5"
16 | kotlin = "2.0.0"
17 | kotlinxSerializationJson = "1.6.3"
18 | ktor = "2.3.12"
19 | lifecycleViewmodel = "2.8.3"
20 | logback = "1.5.6"
21 |
22 | [libraries]
23 | androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "lifecycleViewmodel" }
24 | kamel-image = { module = "media.kamel:kamel-image", version.ref = "kamelImage" }
25 | kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
26 | kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
27 | junit = { group = "junit", name = "junit", version.ref = "junit" }
28 | androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core-ktx" }
29 | androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-junit" }
30 | androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-espresso-core" }
31 | androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" }
32 | androidx-material = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" }
33 | androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" }
34 | androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
35 | kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
36 | logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
37 | ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "ktor" }
38 | ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" }
39 | ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" }
40 | ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
41 | ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
42 | ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
43 |
44 | [plugins]
45 | androidApplication = { id = "com.android.application", version.ref = "agp" }
46 | androidLibrary = { id = "com.android.library", version.ref = "agp" }
47 | jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
48 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
49 | kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
50 | ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
51 | kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/DataSourcesImpl.kt:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import GithubRepositoryData
4 | import OwnerData
5 | import data.models.AllGithubRepositoriesData
6 | import data.models.UserData
7 | import kotlinx.coroutines.delay
8 |
9 | /**
10 | * add expect when integrating with real data sources, if we had to
11 | * do platform specific logic
12 | *
13 | * as this is a sample project, all integration points are grouped in one file for now
14 | * for the sake of simplicity
15 | */
16 | // TODO: data to be fetched from actual datasource
17 | object DataSourcesImpl : DataSources {
18 |
19 | private var userData by cache("data.userData")
20 | private var favorites by cache>("data.favorites")
21 |
22 | override suspend fun getUsernameValidation(): List<(String?) -> Boolean> {
23 | delay(1000) // simulate server delay
24 | return listOf(
25 | { it != null && it.length > 4 },
26 | { it?.contains("@") == true },
27 | )
28 | }
29 |
30 | override suspend fun getPasswordValidations(): List<(String?) -> Boolean> {
31 | delay(1000) // simulate server delay
32 | return listOf({ it != null && it.length > 4 })
33 | }
34 |
35 | override suspend fun postLogin(username: String?, password: String?): UserData {
36 | delay(2000) //simulate server delay
37 | return UserData(id = 0, token = "$username|$password")
38 | }
39 |
40 | override suspend fun saveUser(userData: UserData) {
41 | this.userData = userData
42 | }
43 |
44 | /**
45 | * in a real application we have to handle token refresh and expiration
46 | */
47 | override suspend fun isLoggedIn(): Boolean {
48 | delay(1000) // simulate IO delay
49 | return userData != null
50 | }
51 |
52 | override suspend fun getAllGithubRepositories(): AllGithubRepositoriesData {
53 | // return Json.decodeFromString(GithubRepositoriesMockResponse)
54 | delay(3000) //simulate server delay
55 | return AllGithubRepositoriesData(data = (1..500).map { mockGithubRepository(it) })
56 | }
57 |
58 | override suspend fun addToFavorites(repository: GithubRepositoryData) {
59 | delay(1000) // simulate IO delay
60 | favorites = favorites.orEmpty() + repository
61 | }
62 |
63 | override suspend fun removeFromFavorites(repository: GithubRepositoryData) {
64 | delay(1000) // simulate IO delay
65 | favorites = favorites.orEmpty() - repository
66 | }
67 |
68 | override suspend fun getAllFavorites(): List {
69 | delay(1000) // simulate IO delay
70 | return favorites.orEmpty()
71 | }
72 |
73 | private fun mockGithubRepository(id: Int = 1) = GithubRepositoryData(
74 | id = id.toLong(),
75 | name = "Github Repository $id",
76 | isPrivate = false,
77 | description = "Github Repository $id description section",
78 | stargazersCount = id * 1000,
79 | languagesUrl = "https://api.github.com/repos/octocat/boysenberry-repo-1/languages",
80 | owner = OwnerData(
81 | id = (id * 3000).toLong(),
82 | isPrivate = false,
83 | name = "Author $id",
84 | avatarUrl = "https://picsum.photos/${ratio()}/${ratio()}"
85 | )
86 | )
87 |
88 | private fun ratio(): Int = (150..300).random()
89 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/App.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.material.MaterialTheme
2 | import androidx.compose.material.Surface
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.LaunchedEffect
5 | import androidx.compose.runtime.getValue
6 | import androidx.compose.runtime.mutableStateOf
7 | import androidx.compose.runtime.remember
8 | import androidx.compose.runtime.rememberCoroutineScope
9 | import favorites.adapters.AllFavoritesState
10 | import favorites.ui.FavoritesScreen
11 | import home.adapters.HomeState
12 | import home.ui.HomeScreen
13 | import kotlinx.coroutines.Dispatchers
14 | import kotlinx.coroutines.IO
15 | import kotlinx.coroutines.launch
16 | import login.adapters.LoginState
17 | import login.ui.LoginScreen
18 | import navigation.OnBackPressedChannel
19 | import navigation.Provider
20 | import navigation.adapters.NavigationState
21 | import navigation.core.Screens.Favorites
22 | import navigation.core.Screens.Home
23 | import navigation.core.Screens.Login
24 | import navigation.core.Screens.Splash
25 | import navigation.core.initialize
26 | import org.jetbrains.compose.ui.tooling.preview.Preview
27 | import shared.adapters.StateHolder
28 | import splash.SplashScreen
29 |
30 | private val backChannelProvider = Provider(OnBackPressedChannel())
31 |
32 | @Composable
33 | @Preview
34 | fun App(onBackPressedProvider: @Composable (Provider) -> Unit = {}) {
35 | MaterialTheme {
36 | Surface(color = MaterialTheme.colors.background) {
37 | onBackPressedProvider(backChannelProvider)
38 | val scope = rememberCoroutineScope()
39 | val navigationState by remember { mutableStateOf(NavigationState()) }
40 | LaunchedEffect(Unit) {
41 | scope.launch(Dispatchers.IO) {
42 | navigationState.initialize()
43 | }
44 | }
45 | Screen(navigationState)
46 | }
47 | }
48 | }
49 |
50 | @Composable
51 | fun Screen(
52 | navigationState: NavigationState,
53 | ) {
54 | when (navigationState.screen) {
55 |
56 | Splash -> {
57 | backChannelProvider.value.onBackPressed = null
58 | navigationState.state = null
59 | SplashScreen()
60 | }
61 |
62 | Login -> {
63 | backChannelProvider.value.onBackPressed = null
64 | val holder = StateHolder("LoginState", LoginState())
65 | navigationState.state = holder
66 | LoginScreen(
67 | state = holder.state(),
68 | onSuccess = {
69 | holder.clear()
70 | navigationState.screen = Home
71 | },
72 | )
73 | }
74 |
75 | Home -> {
76 | backChannelProvider.value.onBackPressed = null
77 | val holder = StateHolder("HomeState", HomeState())
78 | navigationState.state = holder
79 | HomeScreen(
80 | state = holder.state(),
81 | onFavoritesClicked = { navigationState.screen = Favorites },
82 | )
83 | }
84 |
85 | Favorites -> {
86 | val holder = StateHolder("AllFavoritesState", AllFavoritesState())
87 | navigationState.state = holder
88 | backChannelProvider.value.onBackPressed = {
89 | holder.clear()
90 | navigationState.screen = Home
91 | }
92 | FavoritesScreen(
93 | state = holder.state(),
94 | onBackPress = {
95 | backChannelProvider.value.onBackPressed?.invoke()
96 | }
97 | )
98 | }
99 | }
100 | }
101 |
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/composeApp/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.compose.desktop.application.dsl.TargetFormat
2 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | alias(libs.plugins.kotlinMultiplatform)
7 | alias(libs.plugins.androidApplication)
8 | alias(libs.plugins.jetbrainsCompose)
9 | alias(libs.plugins.compose.compiler)
10 | kotlin("plugin.serialization") version "2.0.0"
11 | }
12 |
13 | kotlin {
14 | androidTarget {
15 | @OptIn(ExperimentalKotlinGradlePluginApi::class)
16 | compilerOptions {
17 | jvmTarget.set(JvmTarget.JVM_11)
18 | }
19 | }
20 |
21 | jvm("desktop")
22 |
23 | listOf(
24 | iosX64(),
25 | iosArm64(),
26 | iosSimulatorArm64()
27 | ).forEach { iosTarget ->
28 | iosTarget.binaries.framework {
29 | baseName = "ComposeApp"
30 | isStatic = true
31 | }
32 | }
33 |
34 | sourceSets {
35 | val desktopMain by getting
36 |
37 | androidMain.dependencies {
38 | implementation(compose.preview)
39 | implementation(libs.ktor.client.okhttp)
40 | implementation(
41 | libs.androidx.activity.compose.get()
42 | .let { "${it.module}:${it.versionConstraint.requiredVersion}" }) {
43 | exclude(
44 | group = "androidx.lifecycle",
45 | module = "lifecycle-viewmodel-ktx"
46 | )
47 | }
48 | }
49 | commonMain.dependencies {
50 | implementation(compose.runtime)
51 | implementation(compose.foundation)
52 | implementation(compose.material)
53 | implementation(compose.ui)
54 | implementation(compose.components.resources)
55 | implementation(compose.components.uiToolingPreview)
56 | implementation(projects.shared)
57 | implementation(libs.androidx.lifecycle.viewmodel)
58 | implementation(libs.kotlin.test)
59 | implementation(libs.kotlinx.serialization.json)
60 | implementation(libs.kamel.image)
61 | implementation(libs.ktor.client.core)
62 | }
63 | desktopMain.dependencies {
64 | implementation(compose.desktop.currentOs)
65 | implementation(libs.ktor.client.okhttp)
66 | }
67 | iosMain.dependencies {
68 | implementation(libs.ktor.client.darwin)
69 | }
70 | }
71 | }
72 |
73 | android {
74 | namespace = "com.aismail.project"
75 | compileSdk = libs.versions.android.compileSdk.get().toInt()
76 |
77 | sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
78 | sourceSets["main"].res.srcDirs("src/androidMain/res")
79 | sourceSets["main"].resources.srcDirs("src/commonMain/resources")
80 |
81 | defaultConfig {
82 | applicationId = "com.aismail.project"
83 | minSdk = libs.versions.android.minSdk.get().toInt()
84 | targetSdk = libs.versions.android.targetSdk.get().toInt()
85 | versionCode = 1
86 | versionName = "1.0"
87 | }
88 | packaging {
89 | resources {
90 | excludes += "/META-INF/{AL2.0,LGPL2.1}"
91 | }
92 | }
93 | buildTypes {
94 | getByName("release") {
95 | isMinifyEnabled = false
96 | }
97 | }
98 | compileOptions {
99 | sourceCompatibility = JavaVersion.VERSION_11
100 | targetCompatibility = JavaVersion.VERSION_11
101 | }
102 | buildFeatures {
103 | compose = true
104 | }
105 | dependencies {
106 | debugImplementation(compose.uiTooling)
107 | }
108 | }
109 |
110 | compose.desktop {
111 | application {
112 | mainClass = "MainKt"
113 |
114 | nativeDistributions {
115 | targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
116 | packageName = "com.aismail.project"
117 | packageVersion = "1.0.0"
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
24 |
30 |
36 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/login/ui/LoginScreen.kt:
--------------------------------------------------------------------------------
1 | package login.ui
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.fillMaxSize
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.text.KeyboardActions
9 | import androidx.compose.material.Button
10 | import androidx.compose.material.ButtonDefaults
11 | import androidx.compose.material.LinearProgressIndicator
12 | import androidx.compose.material.MaterialTheme
13 | import androidx.compose.material.OutlinedTextField
14 | import androidx.compose.material.Text
15 | import androidx.compose.material.TopAppBar
16 | import androidx.compose.runtime.Composable
17 | import androidx.compose.runtime.LaunchedEffect
18 | import androidx.compose.runtime.remember
19 | import androidx.compose.runtime.rememberCoroutineScope
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.focus.FocusRequester
22 | import androidx.compose.ui.focus.focusRequester
23 | import androidx.compose.ui.graphics.Color
24 | import androidx.compose.ui.platform.LocalFocusManager
25 | import androidx.compose.ui.text.input.PasswordVisualTransformation
26 | import androidx.compose.ui.unit.dp
27 | import kotlinx.coroutines.CoroutineDispatcher
28 | import kotlinx.coroutines.Dispatchers
29 | import kotlinx.coroutines.IO
30 | import kotlinx.coroutines.launch
31 | import login.core.ports.LoginStatePort
32 | import login.core.scenarios.InvalidPasswordException
33 | import login.core.scenarios.InvalidUsernameException
34 | import login.core.scenarios.login
35 |
36 | @Composable
37 | fun LoginScreen(
38 | state: LoginStatePort,
39 | onSuccess: () -> Unit,
40 | modifier: Modifier = Modifier,
41 | dispatcher: CoroutineDispatcher = Dispatchers.IO
42 | ) {
43 | val scope = rememberCoroutineScope()
44 |
45 | LoginScreenContent(
46 | userName = state.userName,
47 | password = state.password,
48 | progress = state.progress,
49 | result = state.result,
50 | onUsernameChanged = { state.userName = it },
51 | onPasswordChanged = { state.password = it },
52 | onLoginClicked = { scope.launch(dispatcher) { state.login() } },
53 | onSuccess = onSuccess,
54 | modifier = modifier
55 | )
56 | }
57 |
58 |
59 | @Composable
60 | fun LoginScreenContent(
61 | userName: String?,
62 | password: String?,
63 | progress: Boolean,
64 | result: LoginStatePort.Result?,
65 | onUsernameChanged: (String?) -> Unit,
66 | onPasswordChanged: (String?) -> Unit,
67 | onLoginClicked: () -> Unit,
68 | onSuccess: () -> Unit,
69 | modifier: Modifier = Modifier
70 | ) {
71 | if (result == LoginStatePort.Result.Success) {
72 | onSuccess()
73 | } else {
74 | val usernameFocusRequester = remember { FocusRequester() }
75 | val passwordFocusRequester = remember { FocusRequester() }
76 |
77 | Column(modifier = modifier.fillMaxSize()) {
78 | TopAppBar(title = { Text(text = "Login", modifier = Modifier.fillMaxWidth()) })
79 | if (progress) LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
80 | Column(
81 | modifier = Modifier.fillMaxSize().padding(16.dp),
82 | verticalArrangement = androidx.compose.foundation.layout.Arrangement.Center,
83 | ) {
84 | UsernameOutlinedTextField(
85 | userName,
86 | result,
87 | usernameFocusRequester,
88 | passwordFocusRequester,
89 | onUsernameChanged
90 | )
91 | PasswordOutlinedTextField(
92 | password,
93 | result,
94 | passwordFocusRequester,
95 | onPasswordChanged,
96 | onLoginClicked
97 | )
98 | LoginButton(progress, onLoginClicked)
99 | }
100 | }
101 |
102 | LaunchedEffect(Unit) {
103 | usernameFocusRequester.requestFocus()
104 | }
105 | }
106 | }
107 |
108 | @Composable
109 | private fun UsernameOutlinedTextField(
110 | userName: String?,
111 | result: LoginStatePort.Result?,
112 | usernameFocusRequester: FocusRequester,
113 | passwordFocusRequester: FocusRequester,
114 | onUsernameChanged: (String?) -> Unit
115 | ) {
116 | OutlinedTextField(
117 | modifier = Modifier
118 | .focusRequester(usernameFocusRequester)
119 | .fillMaxWidth()
120 | .height(80.dp)
121 | .padding(bottom = 16.dp),
122 | value = userName.orEmpty(),
123 | singleLine = true,
124 | label = { Text(text = "Username") },
125 | isError = result is LoginStatePort.Result.Error && result.error is InvalidUsernameException,
126 | onValueChange = onUsernameChanged,
127 | keyboardActions = KeyboardActions(onDone = { passwordFocusRequester.requestFocus() })
128 | )
129 | }
130 |
131 | @Composable
132 | private fun PasswordOutlinedTextField(
133 | password: String?,
134 | result: LoginStatePort.Result?,
135 | focusRequester: FocusRequester,
136 | onPasswordChanged: (String?) -> Unit,
137 | onLoginClicked: () -> Unit
138 | ) {
139 | val focusManager = LocalFocusManager.current
140 | OutlinedTextField(
141 | modifier = Modifier
142 | .focusRequester(focusRequester)
143 | .fillMaxWidth()
144 | .height(80.dp)
145 | .padding(bottom = 16.dp),
146 | value = password.orEmpty(),
147 | label = { Text(text = "Password") },
148 | singleLine = true,
149 | visualTransformation = PasswordVisualTransformation(),
150 | isError = result is LoginStatePort.Result.Error && result.error is InvalidPasswordException,
151 | onValueChange = onPasswordChanged,
152 | keyboardActions = KeyboardActions(onDone = {
153 | focusManager.clearFocus()
154 | onLoginClicked()
155 | })
156 | )
157 | }
158 |
159 | @Composable
160 | private fun LoginButton(progress: Boolean, onLoginClicked: () -> Unit) {
161 | val focusManager = LocalFocusManager.current
162 | Button(
163 | modifier = Modifier
164 | .fillMaxWidth()
165 | .height(80.dp)
166 | .padding(bottom = 16.dp),
167 | colors = ButtonDefaults.buttonColors(backgroundColor = if (!progress) MaterialTheme.colors.primary else Color.Gray),
168 | onClick = {
169 | if (!progress) {
170 | onLoginClicked()
171 | focusManager.clearFocus()
172 | }
173 | }) {
174 | Text(text = "Login")
175 | }
176 | }
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/data/mocks/MockServerResponse.kt:
--------------------------------------------------------------------------------
1 | package data.mocks
2 |
3 | val GithubRepositoriesMockResponse = """
4 | {"data" : [
5 | {
6 | "id": 132935648,
7 | "private": false,
8 | "name": "boysenberry-repo-1",
9 | "description": "Testing",
10 | "stargazers_count": 3,
11 | "languages_url": "https://api.github.com/repos/octocat/boysenberry-repo-1/languages",
12 | "owner": {
13 | "id": 583231,
14 | "private": false,
15 | "name": "octocat",
16 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
17 | }
18 | },
19 | {
20 | "id": 1296269,
21 | "private": false,
22 | "name": "Hello-World",
23 | "description": "My first repository on GitHub!",
24 | "stargazers_count": 1582,
25 | "languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
26 | "owner": {
27 | "id": 583231,
28 | "private": false,
29 | "name": "octocat",
30 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
31 | }
32 | },
33 | {
34 | "id": 18221276,
35 | "private": false,
36 | "name": "git-consortium",
37 | "description": "This repo is for demonstration purposes only.",
38 | "stargazers_count": 4,
39 | "languages_url": "https://api.github.com/repos/octocat/git-consortium/languages",
40 | "owner": {
41 | "id": 583231,
42 | "private": false,
43 | "name": "octocat",
44 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
45 | }
46 | },
47 | {
48 | "id": 54346856,
49 | "private": false,
50 | "name": "Spoon-Knife",
51 | "description": "This repo is for demonstration purposes only.",
52 | "stargazers_count": 10779,
53 | "languages_url": "https://api.github.com/repos/octocat/Spoon-Knife/languages",
54 | "owner": {
55 | "id": 583231,
56 | "private": false,
57 | "name": "octocat",
58 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
59 | }
60 | },
61 | {
62 | "id": 20978623,
63 | "private": false,
64 | "name": "test-repo1",
65 | "description": "Test repo for demonstration purposes.",
66 | "stargazers_count": 0,
67 | "languages_url": "https://api.github.com/repos/octocat/test-repo1/languages",
68 | "owner": {
69 | "id": 583231,
70 | "private": false,
71 | "name": "octocat",
72 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
73 | }
74 | },
75 | {
76 | "id": 45717250,
77 | "private": false,
78 | "name": "test-repo2",
79 | "description": "Another test repo for demonstration purposes.",
80 | "stargazers_count": 1,
81 | "languages_url": "https://api.github.com/repos/octocat/test-repo2/languages",
82 | "owner": {
83 | "id": 583231,
84 | "private": false,
85 | "name": "octocat",
86 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
87 | }
88 | },
89 | {
90 | "id": 63537249,
91 | "private": false,
92 | "name": "test-repo3",
93 | "description": "Yet another test repo for demonstration purposes.",
94 | "stargazers_count": 2,
95 | "languages_url": "https://api.github.com/repos/octocat/test-repo3/languages",
96 | "owner": {
97 | "id": 583231,
98 | "private": false,
99 | "name": "octocat",
100 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
101 | }
102 | },
103 | {
104 | "id": 796307,
105 | "private": false,
106 | "name": "Hello-World2",
107 | "description": "My second repository on GitHub!",
108 | "stargazers_count": 132,
109 | "languages_url": "https://api.github.com/repos/octocat/Hello-World2/languages",
110 | "owner": {
111 | "id": 583231,
112 | "private": false,
113 | "name": "octocat",
114 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
115 | }
116 | },
117 | {
118 | "id": 1296201,
119 | "private": false,
120 | "name": "test-repo4",
121 | "description": "Another test repository.",
122 | "stargazers_count": 12,
123 | "languages_url": "https://api.github.com/repos/octocat/test-repo4/languages",
124 | "owner": {
125 | "id": 583231,
126 | "private": false,
127 | "name": "octocat",
128 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
129 | }
130 | },
131 | {
132 | "id": 234837529,
133 | "private": false,
134 | "name": "test-repo5",
135 | "description": "Test repository for demo purposes.",
136 | "stargazers_count": 3,
137 | "languages_url": "https://api.github.com/repos/octocat/test-repo5/languages",
138 | "owner": {
139 | "id": 583231,
140 | "private": false,
141 | "name": "octocat",
142 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
143 | }
144 | },
145 | {
146 | "id": 1347434,
147 | "private": false,
148 | "name": "test-repo6",
149 | "description": "Another demo test repository.",
150 | "stargazers_count": 0,
151 | "languages_url": "https://api.github.com/repos/octocat/test-repo6/languages",
152 | "owner": {
153 | "id": 583231,
154 | "private": false,
155 | "name": "octocat",
156 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
157 | }
158 | },
159 | {
160 | "id": 767459,
161 | "private": false,
162 | "name": "Hello-World3",
163 | "description": "Third Hello World repository.",
164 | "stargazers_count": 45,
165 | "languages_url": "https://api.github.com/repos/octocat/Hello-World3/languages",
166 | "owner": {
167 | "id": 583231,
168 | "private": false,
169 | "name": "octocat",
170 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
171 | }
172 | },
173 | {
174 | "id": 45157450,
175 | "private": false,
176 | "name": "test-repo7",
177 | "description": "Another repository for testing.",
178 | "stargazers_count": 7,
179 | "languages_url": "https://api.github.com/repos/octocat/test-repo7/languages",
180 | "owner": {
181 | "id": 583231,
182 | "private": false,
183 | "name": "octocat",
184 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
185 | }
186 | },
187 | {
188 | "id": 659478,
189 | "private": false,
190 | "name": "Hello-World4",
191 | "description": "Fourth Hello World repository.",
192 | "stargazers_count": 98,
193 | "languages_url": "https://api.github.com/repos/octocat/Hello-World4/languages",
194 | "owner": {
195 | "id": 583231,
196 | "private": false,
197 | "name": "octocat",
198 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
199 | }
200 | },
201 | {
202 | "id": 57956430,
203 | "private": false,
204 | "name": "test-repo8",
205 | "description": "Yet another test repository.",
206 | "stargazers_count": 5,
207 | "languages_url": "https://api.github.com/repos/octocat/test-repo8/languages",
208 | "owner": {
209 | "id": 583231,
210 | "private": false,
211 | "name": "octocat",
212 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
213 | }
214 | },
215 | {
216 | "id": 65947822,
217 | "private": false,
218 | "name": "Hello-World5",
219 | "description": "Fifth Hello World repository.",
220 | "stargazers_count": 150,
221 | "languages_url": "https://api.github.com/repos/octocat/Hello-World5/languages",
222 | "owner": {
223 | "id": 583231,
224 | "private": false,
225 | "name": "octocat",
226 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4"
227 | }
228 | }
229 | ]
230 | }
231 | """.trimIndent()
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/favorites/ui/FavoritesScreen.kt:
--------------------------------------------------------------------------------
1 | package favorites.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.clickable
5 | import androidx.compose.foundation.layout.Arrangement
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.RowScope
10 | import androidx.compose.foundation.layout.fillMaxHeight
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.lazy.LazyColumn
17 | import androidx.compose.foundation.lazy.items
18 | import androidx.compose.foundation.shape.CircleShape
19 | import androidx.compose.material.CircularProgressIndicator
20 | import androidx.compose.material.Divider
21 | import androidx.compose.material.Icon
22 | import androidx.compose.material.IconButton
23 | import androidx.compose.material.LinearProgressIndicator
24 | import androidx.compose.material.MaterialTheme
25 | import androidx.compose.material.Text
26 | import androidx.compose.material.TopAppBar
27 | import androidx.compose.material.icons.Icons
28 | import androidx.compose.material.icons.automirrored.filled.ArrowBack
29 | import androidx.compose.material.icons.filled.Favorite
30 | import androidx.compose.material.icons.filled.Lock
31 | import androidx.compose.material.icons.filled.Star
32 | import androidx.compose.material.icons.filled.Warning
33 | import androidx.compose.material.icons.sharp.Warning
34 | import androidx.compose.runtime.Composable
35 | import androidx.compose.runtime.LaunchedEffect
36 | import androidx.compose.runtime.rememberCoroutineScope
37 | import androidx.compose.ui.Alignment
38 | import androidx.compose.ui.Modifier
39 | import androidx.compose.ui.draw.clip
40 | import androidx.compose.ui.graphics.painter.Painter
41 | import androidx.compose.ui.layout.ContentScale
42 | import androidx.compose.ui.unit.dp
43 | import favorites.adapters.FavoriteState
44 | import favorites.core.entities.FavoriteRepository
45 | import favorites.core.ports.AllFavoritesStatePort
46 | import favorites.core.ports.FavoriteStatePort
47 | import favorites.core.scenarios.listAll
48 | import io.kamel.core.Resource
49 | import io.kamel.image.asyncPainterResource
50 | import kotlinx.coroutines.CoroutineDispatcher
51 | import kotlinx.coroutines.Dispatchers
52 | import kotlinx.coroutines.IO
53 | import kotlinx.coroutines.withContext
54 |
55 | private val imageModifier =
56 | Modifier.size(width = 70.dp, height = 76.dp).padding(4.dp).clip(CircleShape)
57 |
58 | private val imageProgressModifier =
59 | Modifier.size(width = 70.dp, height = 76.dp).padding(20.dp).clip(CircleShape)
60 |
61 | @Composable
62 | fun FavoritesScreen(
63 | state: AllFavoritesStatePort,
64 | modifier: Modifier = Modifier,
65 | ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
66 | imageLoader: @Composable (String) -> Resource = { asyncPainterResource(it) },
67 | onBackPress: () -> Unit,
68 | ) {
69 |
70 | val scope = rememberCoroutineScope()
71 |
72 | @Composable
73 | fun TopAppBarContent() {
74 | TopAppBar(title = { Text(text = "Favorites", modifier = Modifier.fillMaxWidth()) },
75 | navigationIcon = {
76 | IconButton(onClick = onBackPress) {
77 | Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
78 | }
79 | })
80 | }
81 |
82 | @Composable
83 | fun ListItemsContent(
84 | items: List?,
85 | error: Throwable?,
86 | onItemClicked: (FavoriteStatePort) -> Unit = {}
87 | ) {
88 |
89 | @Composable
90 | fun ErrorContent(error: Throwable) {
91 |
92 | @Composable
93 | fun ErrorText(error: Throwable) {
94 | Text(
95 | text = "An error occurred: ${error.message}",
96 | style = MaterialTheme.typography.subtitle1
97 | )
98 | }
99 |
100 | @Composable
101 | fun ErrorIcon() {
102 | Icon(
103 | Icons.Filled.Warning,
104 | contentDescription = null,
105 | tint = MaterialTheme.colors.error,
106 | modifier = Modifier.size(64.dp)
107 | )
108 | }
109 |
110 | Column(
111 | modifier = Modifier.fillMaxSize().padding(16.dp),
112 | verticalArrangement = Arrangement.Center,
113 | horizontalAlignment = Alignment.CenterHorizontally
114 | ) {
115 | ErrorIcon()
116 | ErrorText(error)
117 | }
118 | }
119 |
120 | @Composable
121 | fun EmptyContent() {
122 | Box(
123 | modifier = Modifier.fillMaxSize().padding(16.dp),
124 | contentAlignment = Alignment.Center
125 | ) {
126 | Text(text = "No Favorites", style = MaterialTheme.typography.h6)
127 | }
128 | }
129 |
130 | @Composable
131 | fun LoadedContent(
132 | listItems: List, onItemClicked: (FavoriteStatePort) -> Unit
133 | ) {
134 |
135 | @Composable
136 | fun ItemContent(
137 | item: FavoriteStatePort, onItemClicked: (FavoriteStatePort) -> Unit
138 | ) {
139 |
140 | @Composable
141 | fun ItemImageSection(imageUrl: String) {
142 |
143 | @Composable
144 | fun FetchedImage(painter: Painter) {
145 | Image(
146 | painter = painter,
147 | contentDescription = null,
148 | contentScale = ContentScale.Crop,
149 | modifier = imageModifier
150 | )
151 | }
152 |
153 | @Composable
154 | fun ErrorImage() {
155 | Icon(
156 | Icons.Sharp.Warning,
157 | tint = MaterialTheme.colors.error,
158 | contentDescription = null,
159 | modifier = imageModifier
160 | )
161 | }
162 |
163 | when (val resource = imageLoader(imageUrl)) {
164 | is Resource.Loading -> CircularProgressIndicator(modifier = imageProgressModifier)
165 | is Resource.Success -> FetchedImage(resource.value)
166 | is Resource.Failure -> ErrorImage()
167 | }
168 | }
169 |
170 | @Composable
171 | fun RowScope.ItemMiddleSection(githubRepository: FavoriteRepository) {
172 | Column(
173 | modifier = Modifier.fillMaxHeight().weight(10f).padding(8.dp),
174 | horizontalAlignment = Alignment.Start,
175 | verticalArrangement = Arrangement.Top
176 | ) {
177 | Text(
178 | text = githubRepository.name.orEmpty(),
179 | style = MaterialTheme.typography.subtitle1
180 | )
181 | Text(
182 | text = githubRepository.ownerName.orEmpty(),
183 | style = MaterialTheme.typography.body2
184 | )
185 | Icon(
186 | Icons.Filled.Favorite,
187 | tint = MaterialTheme.colors.primary,
188 | contentDescription = null,
189 | modifier = Modifier.fillMaxHeight()
190 | )
191 | }
192 | }
193 |
194 | @Composable
195 | fun RowScope.ItemStarsSection(githubRepository: FavoriteRepository) {
196 | Column(
197 | modifier = Modifier.fillMaxHeight().weight(3f).padding(4.dp),
198 | horizontalAlignment = Alignment.End,
199 | verticalArrangement = Arrangement.SpaceEvenly
200 | ) {
201 | Icon(
202 | if (item.progress) Icons.Filled.Lock else Icons.Filled.Star,
203 | contentDescription = null,
204 | tint = MaterialTheme.colors.primary,
205 | modifier = Modifier.size(24.dp)
206 | )
207 | Text(
208 | text = githubRepository.stargazersCount.toString(),
209 | style = MaterialTheme.typography.subtitle1
210 | )
211 | }
212 | }
213 |
214 | Row(
215 | modifier = modifier.height(80.dp).padding(4.dp)
216 | .clickable { onItemClicked(item) },
217 | verticalAlignment = Alignment.CenterVertically,
218 | ) {
219 | ItemImageSection(item.favoriteRepository.avatarUrl.orEmpty())
220 | ItemMiddleSection(item.favoriteRepository)
221 | ItemStarsSection(item.favoriteRepository)
222 | }
223 | }
224 |
225 | LazyColumn {
226 | items(items = listItems, key = { it.favoriteRepository.id }) { item ->
227 | ItemContent(item = item, onItemClicked)
228 | Divider()
229 | }
230 | }
231 | }
232 |
233 | when {
234 | error != null -> ErrorContent(error)
235 | items.isNullOrEmpty() -> EmptyContent()
236 | else -> LoadedContent(items, onItemClicked)
237 | }
238 | }
239 |
240 |
241 | @Composable
242 | fun FavoritesScreenContent() {
243 |
244 | LaunchedEffect(Unit) {
245 | withContext(ioDispatcher) {
246 | state.listAll { FavoriteState(it) }
247 | }
248 | }
249 |
250 | Column(modifier = modifier.fillMaxSize()) {
251 | TopAppBarContent()
252 | if (state.progress) LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
253 | ListItemsContent(
254 | items = state.favorites, error = state.error
255 | )
256 | }
257 | }
258 |
259 | FavoritesScreenContent()
260 | }
261 |
262 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/home/ui/HomeScreen.kt:
--------------------------------------------------------------------------------
1 | package home.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.clickable
5 | import androidx.compose.foundation.layout.Arrangement
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.RowScope
10 | import androidx.compose.foundation.layout.fillMaxHeight
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.lazy.LazyColumn
17 | import androidx.compose.foundation.lazy.items
18 | import androidx.compose.foundation.shape.CircleShape
19 | import androidx.compose.material.AlertDialog
20 | import androidx.compose.material.Button
21 | import androidx.compose.material.CircularProgressIndicator
22 | import androidx.compose.material.Divider
23 | import androidx.compose.material.Icon
24 | import androidx.compose.material.IconButton
25 | import androidx.compose.material.LinearProgressIndicator
26 | import androidx.compose.material.MaterialTheme
27 | import androidx.compose.material.Text
28 | import androidx.compose.material.TopAppBar
29 | import androidx.compose.material.icons.Icons
30 | import androidx.compose.material.icons.filled.Favorite
31 | import androidx.compose.material.icons.filled.Star
32 | import androidx.compose.material.icons.filled.Warning
33 | import androidx.compose.material.icons.sharp.Warning
34 | import androidx.compose.runtime.Composable
35 | import androidx.compose.runtime.LaunchedEffect
36 | import androidx.compose.runtime.getValue
37 | import androidx.compose.runtime.mutableStateOf
38 | import androidx.compose.runtime.remember
39 | import androidx.compose.runtime.rememberCoroutineScope
40 | import androidx.compose.runtime.setValue
41 | import androidx.compose.ui.Alignment
42 | import androidx.compose.ui.Modifier
43 | import androidx.compose.ui.draw.clip
44 | import androidx.compose.ui.graphics.painter.Painter
45 | import androidx.compose.ui.layout.ContentScale
46 | import androidx.compose.ui.unit.dp
47 | import home.adapters.GithubRepositoryState
48 | import home.core.ports.GithubRepositoryStatePort
49 | import home.core.ports.HomeStatePort
50 | import home.core.scenarios.addToFavorites
51 | import home.core.scenarios.listAll
52 | import home.core.scenarios.removeFromFavorites
53 | import io.kamel.core.Resource
54 | import io.kamel.image.asyncPainterResource
55 | import kotlinx.coroutines.CoroutineDispatcher
56 | import kotlinx.coroutines.Dispatchers
57 | import kotlinx.coroutines.IO
58 | import kotlinx.coroutines.launch
59 | import kotlinx.coroutines.withContext
60 |
61 |
62 | private val imageModifier = Modifier
63 | .size(width = 70.dp, height = 76.dp)
64 | .padding(4.dp)
65 | .clip(CircleShape)
66 |
67 | private val imageProgressModifier = Modifier
68 | .size(width = 70.dp, height = 76.dp)
69 | .padding(20.dp)
70 | .clip(CircleShape)
71 |
72 |
73 | @Composable
74 | fun HomeScreen(
75 | state: HomeStatePort,
76 | modifier: Modifier = Modifier,
77 | dispatcher: CoroutineDispatcher = Dispatchers.IO,
78 | imageLoader: @Composable (String) -> Resource = { asyncPainterResource(it) },
79 | onFavoritesClicked: () -> Unit
80 | ) {
81 |
82 | val scope = rememberCoroutineScope()
83 | var favoriteDialogItem: GithubRepositoryStatePort? by remember { mutableStateOf(null) }
84 |
85 | @Composable
86 | fun TopAppBarContent() {
87 |
88 | @Composable
89 | fun FavoritesIconButton() {
90 | IconButton(onClick = { onFavoritesClicked() }) {
91 | Icon(
92 | Icons.Filled.Favorite,
93 | contentDescription = null,
94 | tint = MaterialTheme.colors.background
95 | )
96 | }
97 | }
98 |
99 | TopAppBar(
100 | title = { Text(text = "Home", modifier = Modifier.fillMaxWidth()) },
101 | actions = { FavoritesIconButton() }
102 | )
103 | }
104 |
105 | @Composable
106 | fun ListItemsContent() {
107 |
108 | @Composable
109 | fun ErrorContent() {
110 |
111 | @Composable
112 | fun ErrorText() {
113 | Text(
114 | text = "An error occurred: ${state.error?.message}",
115 | style = MaterialTheme.typography.subtitle1
116 | )
117 | }
118 |
119 | @Composable
120 | fun ErrorIcon() {
121 | Icon(
122 | Icons.Filled.Warning,
123 | contentDescription = null,
124 | tint = MaterialTheme.colors.error,
125 | modifier = Modifier.size(64.dp)
126 | )
127 | }
128 |
129 | Column(
130 | modifier = Modifier.fillMaxSize().padding(16.dp),
131 | verticalArrangement = Arrangement.Center,
132 | horizontalAlignment = Alignment.CenterHorizontally
133 | ) {
134 | ErrorIcon()
135 | ErrorText()
136 | }
137 | }
138 |
139 | @Composable
140 | fun EmptyContent() {
141 | Box(
142 | modifier = Modifier.fillMaxSize().padding(16.dp),
143 | contentAlignment = Alignment.Center
144 | ) {
145 | Text(text = "No repositories", style = MaterialTheme.typography.h6)
146 | }
147 | }
148 |
149 | @Composable
150 | fun LoadedContent() {
151 |
152 | @Composable
153 | fun ItemContent(item: GithubRepositoryStatePort) {
154 |
155 | @Composable
156 | fun ItemImageSection() {
157 |
158 | @Composable
159 | fun FetchedImage(painter: Painter) {
160 | Image(
161 | painter = painter,
162 | contentDescription = null,
163 | contentScale = ContentScale.Crop,
164 | modifier = imageModifier
165 | )
166 | }
167 |
168 | @Composable
169 | fun ErrorImage() {
170 | Icon(
171 | Icons.Sharp.Warning,
172 | tint = MaterialTheme.colors.error,
173 | contentDescription = null,
174 | modifier = imageModifier
175 | )
176 | }
177 |
178 | when (val resource = imageLoader(item.repository.avatarUrl.orEmpty())) {
179 | is Resource.Loading -> CircularProgressIndicator(modifier = imageProgressModifier)
180 | is Resource.Success -> FetchedImage(resource.value)
181 | is Resource.Failure -> ErrorImage()
182 | }
183 | }
184 |
185 | @Composable
186 | fun RowScope.ItemMiddleSection() {
187 | Column(
188 | modifier = Modifier.fillMaxHeight().weight(10f).padding(8.dp),
189 | horizontalAlignment = Alignment.Start,
190 | verticalArrangement = Arrangement.Top
191 | ) {
192 | Text(
193 | text = item.repository.name.orEmpty(),
194 | style = MaterialTheme.typography.subtitle1
195 | )
196 | Text(
197 | text = item.repository.ownerName.orEmpty(),
198 | style = MaterialTheme.typography.body2
199 | )
200 | if (item.isFavorite) Icon(
201 | Icons.Filled.Favorite,
202 | tint = MaterialTheme.colors.primary,
203 | contentDescription = null,
204 | modifier = Modifier.fillMaxHeight()
205 | )
206 | }
207 | }
208 |
209 | @Composable
210 | fun RowScope.ItemStarsSection() {
211 |
212 | @Composable
213 | fun StarIcon() {
214 | Icon(
215 | Icons.Filled.Star,
216 | contentDescription = null,
217 | tint = MaterialTheme.colors.primary,
218 | modifier = Modifier.size(24.dp)
219 | )
220 | }
221 |
222 | Column(
223 | modifier = Modifier.fillMaxHeight().weight(3f).padding(4.dp),
224 | horizontalAlignment = Alignment.End,
225 | verticalArrangement = Arrangement.SpaceEvenly
226 | ) {
227 | if (item.progress) CircularProgressIndicator(modifier = Modifier.size(24.dp))
228 | else StarIcon()
229 | Text(
230 | text = item.repository.stargazersCount.toString(),
231 | style = MaterialTheme.typography.subtitle1
232 | )
233 | }
234 | }
235 |
236 | Row(
237 | modifier = modifier.height(80.dp)
238 | .padding(4.dp)
239 | .clickable { if (!item.progress) favoriteDialogItem = item },
240 | verticalAlignment = Alignment.CenterVertically,
241 | ) {
242 | ItemImageSection()
243 | ItemMiddleSection()
244 | ItemStarsSection()
245 | }
246 | Divider()
247 | }
248 |
249 | LazyColumn {
250 | items(items = state.repositories, key = { it.repository.id }) {
251 | ItemContent(item = it)
252 | }
253 | }
254 | }
255 |
256 | when {
257 | state.error != null -> ErrorContent()
258 | state.repositories.isEmpty() -> EmptyContent()
259 | else -> LoadedContent()
260 | }
261 | }
262 |
263 | @Composable
264 | fun FavoritesDialog() {
265 |
266 | @Composable
267 | fun ConfirmButton() {
268 |
269 | suspend fun onConfirmClicked() {
270 | favoriteDialogItem?.apply {
271 | favoriteDialogItem = null
272 | if (isFavorite) removeFromFavorites() else addToFavorites()
273 | }
274 | }
275 |
276 | Button(onClick = { scope.launch(dispatcher) { onConfirmClicked() } }) {
277 | Text(text = if (favoriteDialogItem?.isFavorite == true) "Remove" else "Add")
278 | }
279 | }
280 |
281 | @Composable
282 | fun TextContent() {
283 | Text(
284 | text = "Are you sure you want to " +
285 | "${if (favoriteDialogItem?.isFavorite == true) "remove" else "add"} " +
286 | "repository ${favoriteDialogItem?.repository?.name} to your favorites?"
287 | )
288 | }
289 |
290 | AlertDialog(
291 | onDismissRequest = { favoriteDialogItem = null },
292 | title = { Text(text = "Favorites") },
293 | text = { TextContent() },
294 | confirmButton = { ConfirmButton() },
295 | dismissButton = { Button(onClick = { favoriteDialogItem = null }) { Text("Cancel") } }
296 | )
297 | }
298 |
299 | @Composable
300 | fun HomeScreenContent() {
301 |
302 | LaunchedEffect(Unit) {
303 | withContext(dispatcher) {
304 | state.listAll(dispatcher) { GithubRepositoryState(it) }
305 | }
306 | }
307 |
308 | if (favoriteDialogItem != null) FavoritesDialog()
309 |
310 | Column(modifier = modifier.fillMaxSize()) {
311 | TopAppBarContent()
312 | if (state.progress) LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
313 | ListItemsContent()
314 | }
315 | }
316 |
317 | HomeScreenContent()
318 | }
319 |
--------------------------------------------------------------------------------