From ac3e03d11e8ddc3b1a6e2089793662bb6f14a3c1 Mon Sep 17 00:00:00 2001 From: Mohsen Mirhoseini Date: Mon, 4 Dec 2023 11:01:37 +0100 Subject: [PATCH] KMP --- .fleet/receipt.json | 24 ++ .gitignore | 8 + .idea/.gitignore | 3 + .idea/.name | 2 +- .idea/artifacts/composeApp_desktop.xml | 8 + .idea/codeStyles/Project.xml | 138 ------ .idea/codeStyles/codeStyleConfig.xml | 6 - .idea/compiler.xml | 2 +- .idea/detekt.xml | 4 + .idea/inspectionProfiles/Project_Default.xml | 7 - .idea/inspectionProfiles/ktlint.xml | 7 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/jarRepositories.xml | 30 -- .idea/migrations.xml | 10 + README.md | 187 ++++---- app/.gitignore | 1 - app/build.gradle.kts | 198 --------- app/proguard-rules.pro | 21 - .../debug/res/xml/network_security_config.xml | 11 - app/src/main/AndroidManifest.xml | 44 -- app/src/main/ic_launcher-web.png | Bin 55400 -> 0 bytes .../rickandmorty/RickAndMortyApplication.kt | 30 -- .../rickandmorty/data/RepositoryImpl.kt | 136 ------ .../rickandmorty/data/api/ApiRickAndMorty.kt | 107 ----- .../data/api/mapper/ApiResultMapper.kt | 55 --- .../data/api/model/ApiCharacter.kt | 44 -- .../rickandmorty/data/api/model/ApiEpisode.kt | 29 -- .../data/api/model/ApiEpisodes.kt | 14 - .../data/api/model/ApiErrorResponse.kt | 18 - .../rickandmorty/data/api/model/ApiInfo.kt | 20 - .../data/api/model/ApiLocation.kt | 14 - .../rickandmorty/data/api/model/ApiOrigin.kt | 14 - .../rickandmorty/data/api/model/ApiResult.kt | 23 - .../mohsenoid/rickandmorty/data/api/module.kt | 17 - .../rickandmorty/data/db/DbRickAndMorty.kt | 77 ---- .../data/db/converters/DbTypeConverters.kt | 41 -- .../data/db/dao/DbCharacterDao.kt | 23 - .../data/db/dao/DbCharacterDaoAbs.kt | 20 - .../rickandmorty/data/db/dao/DbEpisodeDao.kt | 20 - .../rickandmorty/data/db/model/DbCharacter.kt | 54 --- .../rickandmorty/data/db/model/DbEpisode.kt | 33 -- .../rickandmorty/data/db/model/DbLocation.kt | 18 - .../rickandmorty/data/db/model/DbOrigin.kt | 18 - .../mohsenoid/rickandmorty/data/db/module.kt | 10 - .../data/mapper/CharacterMapper.kt | 79 ---- .../rickandmorty/data/mapper/EpisodeMapper.kt | 33 -- .../com/mohsenoid/rickandmorty/data/module.kt | 17 - .../rickandmorty/domain/Repository.kt | 17 - .../domain/model/ModelCharacter.kt | 22 - .../rickandmorty/domain/model/ModelEpisode.kt | 11 - .../domain/model/ModelLocation.kt | 6 - .../rickandmorty/domain/model/ModelOrigin.kt | 6 - .../domain/model/PageQueryResult.kt | 7 - .../rickandmorty/domain/model/QueryResult.kt | 7 - .../com/mohsenoid/rickandmorty/module.kt | 10 - .../rickandmorty/startup/TimberInitializer.kt | 28 -- .../rickandmorty/util/KoinQualifiersNames.kt | 5 - .../rickandmorty/util/StatusProvider.kt | 12 - .../rickandmorty/util/StatusProviderImpl.kt | 38 -- .../rickandmorty/view/MainActivity.kt | 13 - .../details/CharacterDetailsFragment.kt | 97 ----- .../details/CharacterDetailsViewModel.kt | 63 --- .../view/character/details/module.kt | 15 - .../character/list/CharacterListFragment.kt | 104 ----- .../character/list/CharacterListViewModel.kt | 101 ----- .../list/adapter/CharacterListAdapter.kt | 35 -- .../list/adapter/CharacterViewHolder.kt | 14 - .../view/character/list/module.kt | 15 - .../view/episode/list/EpisodeListFragment.kt | 113 ----- .../view/episode/list/EpisodeListViewModel.kt | 92 ---- .../list/adapter/EpisodeListAdapter.kt | 35 -- .../episode/list/adapter/EpisodeViewHolder.kt | 13 - .../rickandmorty/view/episode/list/module.kt | 11 - .../view/mapper/CharacterMapper.kt | 26 -- .../rickandmorty/view/mapper/EpisodeMapper.kt | 11 - .../rickandmorty/view/model/LoadingState.kt | 7 - .../view/model/ViewCharacterItem.kt | 12 - .../view/model/ViewEpisodeItem.kt | 10 - .../rickandmorty/view/util/BindingAdapters.kt | 80 ---- .../util/EndlessRecyclerViewScrollListener.kt | 48 --- .../view/util/LifecycleExtensions.kt | 21 - .../rickandmorty/view/util/SquareImageView.kt | 24 -- app/src/main/res/drawable/ic_alive.xml | 18 - app/src/main/res/drawable/ic_dead.xml | 18 - app/src/main/res/drawable/ic_placeholder.xml | 10 - app/src/main/res/layout/activity_main.xml | 11 - .../res/layout/fragment_character_details.xml | 192 --------- .../res/layout/fragment_character_list.xml | 38 -- .../main/res/layout/fragment_episode_list.xml | 48 --- app/src/main/res/layout/item_character.xml | 52 --- app/src/main/res/layout/item_episode.xml | 53 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3278 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 6418 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 5548 -> 0 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1962 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 3787 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 3248 -> 0 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4816 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 9716 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 8195 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 8264 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 17540 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 13833 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 12347 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 27424 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 20677 -> 0 bytes app/src/main/res/navigation/nav_graph.xml | 38 -- app/src/main/res/values-w600dp/dimens.xml | 5 - app/src/main/res/values/colors.xml | 11 - app/src/main/res/values/dimens.xml | 4 - .../res/values/ic_launcher_background.xml | 4 - app/src/main/res/values/strings.xml | 18 - app/src/main/res/values/styles.xml | 26 -- .../res/xml/network_security_config.xml | 4 - .../data/RepositoryGetCharacterDetailsTest.kt | 68 --- .../data/RepositoryGetCharactersTest.kt | 66 --- .../data/RepositoryGetEpisodesTest.kt | 62 --- .../rickandmorty/data/RepositoryTest.kt | 39 -- .../data/db/DbRickAndMortyTest.kt | 253 ----------- .../data/mapper/CharacterMapperTest.kt | 126 ------ .../data/mapper/EpisodeMapperTest.kt | 85 ---- .../rickandmorty/injection/AppModuleTest.kt | 24 -- .../rickandmorty/injection/DataModuleTest.kt | 35 -- .../rickandmorty/injection/ModuleTest.kt | 30 -- .../mohsenoid/rickandmorty/test/ApiFactory.kt | 149 ------- .../rickandmorty/test/CharacterDataFactory.kt | 97 ----- .../rickandmorty/test/DataFactory.kt | 35 -- .../rickandmorty/test/EpisodeDataFactory.kt | 69 --- .../rickandmorty/test/LocationDataFactory.kt | 26 -- .../rickandmorty/test/OriginDataFactory.kt | 26 -- build.gradle.kts | 34 +- composeApp/build.gradle.kts | 128 ++++++ .../src/androidMain/AndroidManifest.xml | 23 + .../androidMain/kotlin/Platform.android.kt | 7 + .../mohsenoid/rickandmorty/MainActivity.kt | 37 ++ .../drawable-v24/ic_launcher_foreground.xml | 30 ++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3593 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5339 bytes .../res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2636 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3388 bytes .../res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4926 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7472 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7909 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 11873 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10652 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 16570 bytes .../src/androidMain/res/values/strings.xml | 3 + composeApp/src/commonMain/kotlin/App.kt | 95 ++++ composeApp/src/commonMain/kotlin/Greeting.kt | 7 + composeApp/src/commonMain/kotlin/NavRoute.kt | 8 + composeApp/src/commonMain/kotlin/Platform.kt | 5 + .../episode/data/EpisodeRemoteDataSource.kt | 32 ++ .../episode/data/EpisodeRepositoryImpl.kt | 51 +++ .../episode/data/model/CharacterResponse.kt | 33 ++ .../data/model/CharacterResponseLocation.kt | 13 + .../data/model/CharacterResponseOrigin.kt | 13 + .../episode/data/model/EpisodeResponse.kt | 23 + .../episode/domain/EpisodeRepository.kt | 8 + .../kotlin/episode/domain/model/Character.kt | 28 +- .../kotlin/episode/domain/model/Episode.kt | 8 + .../episode/presentation/EpisodeScreen.kt | 95 ++++ .../episode/presentation/EpisodeUiState.kt | 9 + .../episode/presentation/EpisodeViewModel.kt | 28 ++ .../episodes/data/EpisodesRemoteDataSource.kt | 29 ++ .../episodes/data/EpisodesRepositoryImpl.kt | 26 ++ .../episodes/data/model/EpisodesResponse.kt | 12 + .../data/model/EpisodesResponseInfo.kt | 16 + .../data/model/EpisodesResponseResult.kt | 22 + .../episodes/domain/EpisodesRepository.kt | 8 + .../kotlin/episodes/domain/model/Episode.kt | 10 + .../episodes/presentation/EpisodesScreen.kt | 87 ++++ .../episodes/presentation/EpisodesUiState.kt | 9 + .../presentation/EpisodesViewModel.kt | 25 ++ .../src/commonMain/kotlin/theme/Color.kt | 10 + .../src/commonMain/kotlin/theme/Theme.kt | 47 ++ .../src/commonMain/kotlin/theme/Type.kt | 34 ++ .../resources/compose-multiplatform.xml | 36 ++ .../src/desktopMain/kotlin/Platform.jvm.kt | 5 + composeApp/src/desktopMain/kotlin/main.kt | 16 + .../src/iosMain/kotlin/MainViewController.kt | 3 + composeApp/src/iosMain/kotlin/Platform.ios.kt | 7 + gradle.properties | 38 +- gradle/libs.versions.toml | 57 +++ gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 281 +++++++----- gradlew.bat | 181 ++++---- iosApp/Configuration/Config.xcconfig | 3 + iosApp/iosApp.xcodeproj/project.pbxproj | 408 ++++++++++++++++++ .../xcschemes/iosApp.xcscheme | 32 ++ .../xcschemes/xcschememanagement.plist | 14 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 14 + .../AppIcon.appiconset/app-icon-1024.png | Bin 0 -> 67285 bytes iosApp/iosApp/Assets.xcassets/Contents.json | 6 + iosApp/iosApp/ContentView.swift | 21 + iosApp/iosApp/Info.plist | 50 +++ .../Preview Assets.xcassets/Contents.json | 6 + iosApp/iosApp/iOSApp.swift | 10 + settings.gradle | 2 - settings.gradle.kts | 21 + 206 files changed, 2359 insertions(+), 4660 deletions(-) create mode 100644 .fleet/receipt.json create mode 100644 .idea/.gitignore create mode 100644 .idea/artifacts/composeApp_desktop.xml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/ktlint.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/migrations.xml delete mode 100644 app/.gitignore delete mode 100644 app/build.gradle.kts delete mode 100644 app/proguard-rules.pro delete mode 100644 app/src/debug/res/xml/network_security_config.xml delete mode 100644 app/src/main/AndroidManifest.xml delete mode 100644 app/src/main/ic_launcher-web.png delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/RickAndMortyApplication.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/RepositoryImpl.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/ApiRickAndMorty.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/mapper/ApiResultMapper.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiCharacter.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisode.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisodes.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiErrorResponse.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiInfo.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiLocation.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiOrigin.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiResult.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMorty.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/converters/DbTypeConverters.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDao.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDaoAbs.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbEpisodeDao.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbCharacter.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbEpisode.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbLocation.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbOrigin.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapper.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapper.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/data/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/Repository.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelCharacter.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelEpisode.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelLocation.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelOrigin.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/PageQueryResult.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/QueryResult.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/startup/TimberInitializer.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/util/KoinQualifiersNames.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProvider.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProviderImpl.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/MainActivity.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsFragment.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsViewModel.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListFragment.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListViewModel.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterListAdapter.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterViewHolder.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListFragment.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListViewModel.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeListAdapter.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeViewHolder.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/module.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/CharacterMapper.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/EpisodeMapper.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/LoadingState.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterItem.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewEpisodeItem.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/BindingAdapters.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/EndlessRecyclerViewScrollListener.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/LifecycleExtensions.kt delete mode 100644 app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/SquareImageView.kt delete mode 100644 app/src/main/res/drawable/ic_alive.xml delete mode 100644 app/src/main/res/drawable/ic_dead.xml delete mode 100644 app/src/main/res/drawable/ic_placeholder.xml delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/layout/fragment_character_details.xml delete mode 100644 app/src/main/res/layout/fragment_character_list.xml delete mode 100644 app/src/main/res/layout/fragment_episode_list.xml delete mode 100644 app/src/main/res/layout/item_character.xml delete mode 100644 app/src/main/res/layout/item_episode.xml delete mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/navigation/nav_graph.xml delete mode 100644 app/src/main/res/values-w600dp/dimens.xml delete mode 100644 app/src/main/res/values/colors.xml delete mode 100644 app/src/main/res/values/dimens.xml delete mode 100644 app/src/main/res/values/ic_launcher_background.xml delete mode 100644 app/src/main/res/values/strings.xml delete mode 100644 app/src/main/res/values/styles.xml delete mode 100644 app/src/release/res/xml/network_security_config.xml delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharacterDetailsTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharactersTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetEpisodesTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMortyTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapperTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapperTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/AppModuleTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/DataModuleTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/ModuleTest.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/ApiFactory.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/CharacterDataFactory.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/DataFactory.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/EpisodeDataFactory.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/LocationDataFactory.kt delete mode 100644 app/src/test/kotlin/com/mohsenoid/rickandmorty/test/OriginDataFactory.kt create mode 100644 composeApp/build.gradle.kts create mode 100644 composeApp/src/androidMain/AndroidManifest.xml create mode 100644 composeApp/src/androidMain/kotlin/Platform.android.kt create mode 100644 composeApp/src/androidMain/kotlin/com/mohsenoid/rickandmorty/MainActivity.kt create mode 100644 composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 composeApp/src/androidMain/res/drawable/ic_launcher_background.xml create mode 100644 composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png create mode 100644 composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png create mode 100644 composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png create mode 100644 composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 composeApp/src/androidMain/res/values/strings.xml create mode 100644 composeApp/src/commonMain/kotlin/App.kt create mode 100644 composeApp/src/commonMain/kotlin/Greeting.kt create mode 100644 composeApp/src/commonMain/kotlin/NavRoute.kt create mode 100644 composeApp/src/commonMain/kotlin/Platform.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/EpisodeRemoteDataSource.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/EpisodeRepositoryImpl.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponse.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseLocation.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseOrigin.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/data/model/EpisodeResponse.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/domain/EpisodeRepository.kt rename app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterDetails.kt => composeApp/src/commonMain/kotlin/episode/domain/model/Character.kt (57%) create mode 100644 composeApp/src/commonMain/kotlin/episode/domain/model/Episode.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/presentation/EpisodeScreen.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/presentation/EpisodeUiState.kt create mode 100644 composeApp/src/commonMain/kotlin/episode/presentation/EpisodeViewModel.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/data/EpisodesRemoteDataSource.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/data/EpisodesRepositoryImpl.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponse.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseInfo.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseResult.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/domain/EpisodesRepository.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/domain/model/Episode.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesScreen.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesUiState.kt create mode 100644 composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesViewModel.kt create mode 100644 composeApp/src/commonMain/kotlin/theme/Color.kt create mode 100644 composeApp/src/commonMain/kotlin/theme/Theme.kt create mode 100644 composeApp/src/commonMain/kotlin/theme/Type.kt create mode 100644 composeApp/src/commonMain/resources/compose-multiplatform.xml create mode 100644 composeApp/src/desktopMain/kotlin/Platform.jvm.kt create mode 100644 composeApp/src/desktopMain/kotlin/main.kt create mode 100644 composeApp/src/iosMain/kotlin/MainViewController.kt create mode 100644 composeApp/src/iosMain/kotlin/Platform.ios.kt create mode 100644 gradle/libs.versions.toml create mode 100644 iosApp/Configuration/Config.xcconfig create mode 100644 iosApp/iosApp.xcodeproj/project.pbxproj create mode 100644 iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/iosApp.xcscheme create mode 100644 iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png create mode 100644 iosApp/iosApp/Assets.xcassets/Contents.json create mode 100644 iosApp/iosApp/ContentView.swift create mode 100644 iosApp/iosApp/Info.plist create mode 100644 iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 iosApp/iosApp/iOSApp.swift delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/.fleet/receipt.json b/.fleet/receipt.json new file mode 100644 index 0000000..2393e03 --- /dev/null +++ b/.fleet/receipt.json @@ -0,0 +1,24 @@ +// Project generated by Kotlin Multiplatform Wizard +{ + "spec": { + "template_id": "kmt", + "targets": { + "android": { + "ui": [ + "compose" + ] + }, + "ios": { + "ui": [ + "compose" + ] + }, + "desktop": { + "ui": [ + "compose" + ] + } + } + }, + "timestamp": "2023-12-03T19:28:10.118100282Z" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c91a391..014127c 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,11 @@ lint/generated/ lint/outputs/ lint/tmp/ # lint/reports/ + +.cxx +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcodeproj/project.xcworkspace/ +!*.xcworkspace/contents.xcworkspacedata +**/xcshareddata/WorkspaceSettings.xcsettings diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name index b8117e7..d69616e 100644 --- a/.idea/.name +++ b/.idea/.name @@ -1 +1 @@ -Rick and Morty \ No newline at end of file +RickandMorty \ No newline at end of file diff --git a/.idea/artifacts/composeApp_desktop.xml b/.idea/artifacts/composeApp_desktop.xml new file mode 100644 index 0000000..2858e5a --- /dev/null +++ b/.idea/artifacts/composeApp_desktop.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/composeApp/build/libs + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 7829f3c..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
- - -
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 6e6eec1..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8..b589d56 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/detekt.xml b/.idea/detekt.xml index d7ca9af..bfab4a3 100644 --- a/.idea/detekt.xml +++ b/.idea/detekt.xml @@ -1,5 +1,9 @@ + + true true diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 9029a53..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/ktlint.xml b/.idea/inspectionProfiles/ktlint.xml deleted file mode 100644 index 7d04a74..0000000 --- a/.idea/inspectionProfiles/ktlint.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 64580d1..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index e34606c..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 75ad4d2..0fe79d2 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,102 @@ -# ![launcher icon](logo.png) Rick and Morty [![Actions Status](https://github.com/mohsenoid/Rick-and-Morty/workflows/Android%20CI/badge.svg)](https://github.com/mohsenoid/Rick-and-Morty/actions) [![codecov](https://codecov.io/gh/mohsenoid/Rick-and-Morty/branch/master/graph/badge.svg)](https://codecov.io/gh/mohsenoid/Rick-and-Morty) [![CodeFactor](https://www.codefactor.io/repository/github/mohsenoid/rick-and-morty/badge)](https://www.codefactor.io/repository/github/mohsenoid/rick-and-morty) - -This repository contains Rick and Morty Android application which I am using as training material. - -![Screenshot](SCREENSHOT1.png) ![Screenshot](SCREENSHOT2.png) - -## User Stories - -1. The first thing a user should see is a list of episodes. -2. If the user taps into an episode the app has to display a list of characters with a clear distinction between dead and alive characters -3. If the user taps into a character the app has to display that character's picture and information. -4. The user should have the ability to kill a character and if a character gets killed the character lists should update accordingly - -## Functionality - -The app is composed of 3 main screens: - -### Episodes List - -It allows you to list episodes in pages. Network results are kept in the database in the `episodes` table. Each time a new page is fetched, the same `episode` record in the database is updated with the new data. - -### Episode's Characters List - -Shows you the list of episode characters. Network results are also kept in the database in the `characters table`. Each time a new character is fetched, the same `character` record in the database is updated with the new data and we make sure we don't override *is killed by user* data. - -### Character Details - -This screen displays the details of a character and if *is killed by the user*. - -## Building - -You can clone and open the project in Android studio and press run! - -## Testing - -The project uses local unit tests that run on your computer. To run those tests and generate a coverage report, you can run: - - ./gradlew jacocoReport - -***NOTE:*** You can find the tests report in `app/build/reports/jacoco/jacocoReport/html/index.html` - -## Technical details - -The Application implemented and structured based on **Clean Architecture** and **SOLID** principles best practices and the presentation layer is implemented based on the **MVP** pattern. - -The **Data** layer contains **Network Client** implemented by *Retrofit* library to get access to remote data on [Rick And Morty API](https://rickandmortyapi.com/) and **DB** implemented by *Room* library to cache and persist those data locally in case of offline usage. - -The **Domain** layer consists of a **Repository** which allows access to the Data layer. It also uses *Kotlin Coroutines* **IO** and **Main** *dispatchers* to execute long-running tasks in the background and reflect the result on UI. There is also a **Test** *dispatcher* that executes tasks immediately on the same unit test thread. - -![Repository Pattern](REPOSITORY_PATTERN.png) - -The **View** layer is done with the [Android Navigation Component](https://developer.android.com/guide/navigation) including one MainActivity which holds the navigation host fragment and 3 different Fragments which uses their contract interfaces to implement the *view* and *presenter* for responding to user interactions. - -![Navigation Graph](NAV_GRAPH.png) - -The **Koin** library does the *dependency injections* in the whole app. It also uses **Base** objects to define scopes and inject dependencies into **Activities** and **Fragments**. - -[**GitHub Actions CI service**](https://github.com/mohsenoid/Rick-and-Morty/actions) is running the repo tests and build Gradle tasks and **jacoco** plugin generates and submits the code coverage reports to [**codecov.io**](https://codecov.io/gh/mohsenoid/Rick-and-Morty). - -Code is covered by unit tests implemented using **Mockito** and **Kluent**. Also, some Android tests using **Robolectric**. - -## Libraries - -- **Timber** logger library made by [Jake Wharton](https://github.com/JakeWharton/timber) -- **Picasso** image downloading and caching library made by [square](https://github.com/square/picasso) -- **Retrofit** and **OkHttp** API libraries made by [square](https://github.com/square/retrofit) -- **Kotlin Serialization** plugin made by [jetbrains](https://github.com/Kotlin/kotlinx.serialization) -- **Koin** dependency injector library made by [InsertKoinIO](https://github.com/InsertKoinIO/koin) -- **Kluent** assertions library made by [MarkusAmshove](https://github.com/MarkusAmshove/Kluent) - -### References - -- App **Launcher Icon** made by [freepngimg.com](http://freepngimg.com) - -- **Dead/Alive Icons** made by [Freepik](https://flaticon.com/authors/freepik) from [flaticon.com](https://flaticon.com) - -## License - -Copyright 2020 Mohsen Mirhoseini Argi - -Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +# ![launcher icon](logo.png) Rick and Morty [![Actions Status](https://github.com/mohsenoid/Rick-and-Morty/workflows/Android%20CI/badge.svg)](https://github.com/mohsenoid/Rick-and-Morty/actions) [![codecov](https://codecov.io/gh/mohsenoid/Rick-and-Morty/branch/master/graph/badge.svg)](https://codecov.io/gh/mohsenoid/Rick-and-Morty) [![CodeFactor](https://www.codefactor.io/repository/github/mohsenoid/rick-and-morty/badge)](https://www.codefactor.io/repository/github/mohsenoid/rick-and-morty) + +This repository contains Rick and Morty Android application which I am using as training material. + +![Screenshot](SCREENSHOT1.png) ![Screenshot](SCREENSHOT2.png) + +## User Stories + +1. The first thing a user should see is a list of episodes. +2. If the user taps into an episode the app has to display a list of characters with a clear distinction between dead and alive characters +3. If the user taps into a character the app has to display that character's picture and information. +4. The user should have the ability to kill a character and if a character gets killed the character lists should update accordingly + +## Functionality + +The app is composed of 3 main screens: + +### Episodes List + +It allows you to list episodes in pages. Network results are kept in the database in the `episodes` table. Each time a new page is fetched, the same `episode` record in the database is updated with the new data. + +### Episode's Characters List + +Shows you the list of episode characters. Network results are also kept in the database in the `characters table`. Each time a new character is fetched, the same `character` record in the database is updated with the new data and we make sure we don't override *is killed by user* data. + +### Character Details + +This screen displays the details of a character and if *is killed by the user*. + +## Building + +You can clone and open the project in Android studio and press run! + +## Testing + +The project uses local unit tests that run on your computer. To run those tests and generate a coverage report, you can run: + + ./gradlew jacocoReport + +***NOTE:*** You can find the tests report in `app/build/reports/jacoco/jacocoReport/html/index.html` + +## Technical details + +The Application implemented and structured based on **Clean Architecture** and **SOLID** principles best practices and the presentation layer is implemented based on the **MVP** pattern. + +The **Data** layer contains **Network Client** implemented by *Retrofit* library to get access to remote data on [Rick And Morty API](https://rickandmortyapi.com/) and **DB** implemented by *Room* library to cache and persist those data locally in case of offline usage. + +The **Domain** layer consists of a **Repository** which allows access to the Data layer. It also uses *Kotlin Coroutines* **IO** and **Main** *dispatchers* to execute long-running tasks in the background and reflect the result on UI. There is also a **Test** *dispatcher* that executes tasks immediately on the same unit test thread. + +![Repository Pattern](REPOSITORY_PATTERN.png) + +The **View** layer is done with the [Android Navigation Component](https://developer.android.com/guide/navigation) including one MainActivity which holds the navigation host fragment and 3 different Fragments which uses their contract interfaces to implement the *view* and *presenter* for responding to user interactions. + +![Navigation Graph](NAV_GRAPH.png) + +The **Koin** library does the *dependency injections* in the whole app. It also uses **Base** objects to define scopes and inject dependencies into **Activities** and **Fragments**. + +[**GitHub Actions CI service**](https://github.com/mohsenoid/Rick-and-Morty/actions) is running the repo tests and build Gradle tasks and **jacoco** plugin generates and submits the code coverage reports to [**codecov.io**](https://codecov.io/gh/mohsenoid/Rick-and-Morty). + +Code is covered by unit tests implemented using **Mockito** and **Kluent**. Also, some Android tests using **Robolectric**. + +## Libraries + +- **Timber** logger library made by [Jake Wharton](https://github.com/JakeWharton/timber) +- **Picasso** image downloading and caching library made by [square](https://github.com/square/picasso) +- **Retrofit** and **OkHttp** API libraries made by [square](https://github.com/square/retrofit) +- **Kotlin Serialization** plugin made by [jetbrains](https://github.com/Kotlin/kotlinx.serialization) +- **Koin** dependency injector library made by [InsertKoinIO](https://github.com/InsertKoinIO/koin) +- **Kluent** assertions library made by [MarkusAmshove](https://github.com/MarkusAmshove/Kluent) + +### References + +- App **Launcher Icon** made by [freepngimg.com](http://freepngimg.com) + +- **Dead/Alive Icons** made by [Freepik](https://flaticon.com/authors/freepik) from [flaticon.com](https://flaticon.com) + +## License + +Copyright 2020 Mohsen Mirhoseini Argi + +Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +----- + +This is a Kotlin Multiplatform project targeting Android, iOS, Desktop. + +* `/composeApp` is for code that will be shared across your Compose Multiplatform applications. + It contains several subfolders: + - `commonMain` is for code that’s common for all targets. + - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. + For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, + `iosMain` would be the right folder for such calls. + +* `/iosApp` contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, + you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project. + + +Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)… diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/app/build.gradle.kts b/app/build.gradle.kts deleted file mode 100644 index e868a0b..0000000 --- a/app/build.gradle.kts +++ /dev/null @@ -1,198 +0,0 @@ -import org.jlleitschuh.gradle.ktlint.reporter.ReporterType - -plugins { - id("com.android.application") - kotlin("android") - kotlin("kapt") - kotlin("plugin.serialization") version "1.5.31" - id("org.jetbrains.dokka") version "1.5.30" - id("androidx.navigation.safeargs.kotlin") - - id("io.gitlab.arturbosch.detekt") version "1.18.1" - id("org.jlleitschuh.gradle.ktlint") version "10.2.0" - - jacoco -} - -android { - compileSdk = 31 - - defaultConfig { - applicationId = "com.mohsenoid.rickandmorty" - - minSdk = 24 - targetSdk = 31 - multiDexEnabled = true - - versionCode = 10 - versionName = "2.7.0" - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - defaultConfig { - buildConfigField("String", "BASE_URL", "\"https://rickandmortyapi.com/api/\"") - } - - debug { - isMinifyEnabled = false - isTestCoverageEnabled = true - } - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - sourceSets { - getByName("main") { - java { - srcDirs("src/main/kotlin") - srcDirs("${buildDir.absolutePath}/generated/source/kaptKotlin/") - } - } - getByName("test") { - java { - srcDirs("src/test/kotlin") - } - } - getByName("androidTest") { - java { - srcDirs("src/androidTest/kotlin") - } - } - } - - testOptions { - execution = "ANDROIDX_TEST_ORCHESTRATOR" - animationsDisabled = true - - unitTests { - isIncludeAndroidResources = true - } - } - - buildFeatures { - dataBinding = true - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlinOptions { - allWarningsAsErrors = true - jvmTarget = JavaVersion.VERSION_11.toString() - freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn") - } - - lint { - isIgnoreWarnings = false - isWarningsAsErrors = true - } -} - -// https://arturbosch.github.io/detekt/#quick-start-with-gradle -detekt { - allRules = true - source = files("src/main/kotlin/") - baseline = file("detekt-baseline.xml") - buildUponDefaultConfig = true - reports { - html { enabled = true } - xml { enabled = true } - txt { enabled = false } - } -} - -// https://github.com/JLLeitschuh/ktlint-gradle#configuration -ktlint { - reporters { - reporter(ReporterType.HTML) - reporter(ReporterType.CHECKSTYLE) - } -} - -// https://docs.gradle.org/current/userguide/jacoco_plugin.html -jacoco { - toolVersion = "0.8.7" -} - -dependencies { - // Android Jetpack - implementation("androidx.appcompat:appcompat:1.4.0") - implementation("androidx.core:core-ktx:1.7.0") - implementation("androidx.recyclerview:recyclerview:1.2.1") - implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") - implementation("androidx.cardview:cardview:1.0.0") - implementation("androidx.multidex:multidex:2.0.1") - testImplementation("androidx.test:core:1.4.0") - testImplementation("androidx.arch.core:core-testing:2.1.0") - androidTestImplementation("androidx.test.ext:junit:1.1.3") - androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") - - // Kotlin - implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.5.31")) - implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1") - - implementation(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2")) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android") - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test") - - dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.5.30") - - // Test - testImplementation("junit:junit:4.13.2") - testImplementation("org.robolectric:robolectric:4.7.2") - testImplementation("io.mockk:mockk:1.12.1") - - // Koin - val koinVersion = "3.1.4" - implementation("io.insert-koin:koin-android:$koinVersion") - implementation("io.insert-koin:koin-android-compat:$koinVersion") - testImplementation("io.insert-koin:koin-test:$koinVersion") - - // Retrofit - implementation("com.squareup.retrofit2:retrofit:2.9.0") - implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0") - val okhttpVersion = "4.9.3" - implementation("com.squareup.okhttp3:okhttp:$okhttpVersion") - implementation("com.squareup.okhttp3:logging-interceptor:$okhttpVersion") - - // Room - val roomVersion = "2.3.0" - implementation("androidx.room:room-runtime:$roomVersion") - kapt("androidx.room:room-compiler:$roomVersion") - implementation("androidx.room:room-ktx:$roomVersion") - - // Navigation component - val navigationComponentVersion = "2.3.5" - implementation("androidx.navigation:navigation-fragment-ktx:$navigationComponentVersion") - implementation("androidx.navigation:navigation-ui-ktx:$navigationComponentVersion") - implementation("androidx.navigation:navigation-dynamic-features-fragment:$navigationComponentVersion") - androidTestImplementation("androidx.navigation:navigation-testing:$navigationComponentVersion") - - // timber - implementation("com.jakewharton.timber:timber:5.0.1") - - // picasso - implementation("com.squareup.picasso:picasso:2.71828") - - // chucker - val chuckerVersion = "3.5.2" - debugImplementation("com.github.chuckerteam.chucker:library:$chuckerVersion") - releaseImplementation("com.github.chuckerteam.chucker:library-no-op:$chuckerVersion") - - // leakcanary - debugImplementation("com.squareup.leakcanary:leakcanary-android:2.7") - - // Startup - implementation("androidx.startup:startup-runtime:1.1.0") -} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/app/src/debug/res/xml/network_security_config.xml b/app/src/debug/res/xml/network_security_config.xml deleted file mode 100644 index f17a19f..0000000 --- a/app/src/debug/res/xml/network_security_config.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml deleted file mode 100644 index 576c956..0000000 --- a/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png deleted file mode 100644 index 46f35841793c69335324f8b2a43c9b4391e9de71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55400 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 = mapOf( - KoinQualifiersNames.BASE_URL to BuildConfig.BASE_URL, - ) - properties(appProperties) - - if (isDebug) androidLogger() - - androidContext(this@RickAndMortyApplication) - modules(appModule + dataModule) - } - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/RepositoryImpl.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/RepositoryImpl.kt deleted file mode 100644 index 0adec23..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/RepositoryImpl.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.ApiRickAndMorty -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisode -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import com.mohsenoid.rickandmorty.data.db.DbRickAndMorty -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.data.mapper.toDbCharacter -import com.mohsenoid.rickandmorty.data.mapper.toDbEpisode -import com.mohsenoid.rickandmorty.data.mapper.toModelCharacter -import com.mohsenoid.rickandmorty.data.mapper.toModelEpisode -import com.mohsenoid.rickandmorty.domain.Repository -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode -import com.mohsenoid.rickandmorty.domain.model.PageQueryResult -import com.mohsenoid.rickandmorty.domain.model.QueryResult -import com.mohsenoid.rickandmorty.util.StatusProvider - -@Suppress("TooManyFunctions") -class RepositoryImpl internal constructor( - private val db: DbRickAndMorty, - private val api: ApiRickAndMorty, - private val statusProvider: StatusProvider, -) : Repository { - - override suspend fun getEpisodes(page: Int): PageQueryResult> { - if (statusProvider.isOnline()) { - val result = fetchNetworkEpisodes(page) - if (result is PageQueryResult.Successful) cacheNetworkEpisodes(result.data) - } - - return queryDbEpisodes(page, PAGE_SIZE) - } - - private suspend fun fetchNetworkEpisodes(page: Int): PageQueryResult> = - when (val result = api.fetchEpisodes(page)) { - is ApiResult.Success -> PageQueryResult.Successful(result.data.results) - is ApiResult.Error.ServerError, - is ApiResult.Error.UnknownError, - -> PageQueryResult.Error - } - - private suspend fun cacheNetworkEpisodes(episodes: List) { - episodes.map(ApiEpisode::toDbEpisode) - .forEach { db.insertEpisode(it) } - } - - private suspend fun queryDbEpisodes( - page: Int, - pageSize: Int, - ): PageQueryResult> { - val dbEntityEpisodes: List = db.queryAllEpisodesByPage(page, pageSize) - val episodes: List = dbEntityEpisodes.map(DbEpisode::toModelEpisode) - - if (episodes.isEmpty()) return PageQueryResult.EndOfList - - return PageQueryResult.Successful(episodes) - } - - override suspend fun getCharactersByIds( - characterIds: List, - ): QueryResult> { - if (statusProvider.isOnline()) { - val result = fetchNetworkCharactersByIds(characterIds) - if (result is QueryResult.Successful) cacheNetworkCharacters(result.data) - } - - return queryDbCharactersByIds(characterIds) - } - - private suspend fun fetchNetworkCharactersByIds( - characterIds: List, - ): QueryResult> = - when (val result = api.fetchCharactersByIds(characterIds.joinToString(","))) { - is ApiResult.Success -> QueryResult.Successful(result.data) - is ApiResult.Error.ServerError, - is ApiResult.Error.UnknownError, - -> QueryResult.Error - } - - private suspend fun cacheNetworkCharacters(characters: List) { - characters.map(ApiCharacter::toDbCharacter) - .forEach { db.insertOrUpdateCharacter(it) } - } - - private suspend fun queryDbCharactersByIds( - characterIds: List, - ): QueryResult> { - val dbCharacters: List = db.queryCharactersByIds(characterIds) - - val characters: List = dbCharacters.map(DbCharacter::toModelCharacter) - - if (characters.isEmpty()) QueryResult.NoCache - - return QueryResult.Successful(characters) - } - - override suspend fun getCharacterDetails(characterId: Int): QueryResult { - if (statusProvider.isOnline()) { - val result = fetchNetworkCharacterDetails(characterId) - if (result is QueryResult.Successful) cacheNetworkCharacter(result.data) - } - - return queryDbCharacterDetails(characterId) - } - - private suspend fun fetchNetworkCharacterDetails(characterId: Int): QueryResult = - when (val result = api.fetchCharacterDetails(characterId)) { - is ApiResult.Success -> QueryResult.Successful(result.data) - is ApiResult.Error.ServerError, - is ApiResult.Error.UnknownError, - -> QueryResult.Error - } - - private suspend fun cacheNetworkCharacter(character: ApiCharacter) { - db.insertOrUpdateCharacter(character.toDbCharacter()) - } - - private suspend fun queryDbCharacterDetails(characterId: Int): QueryResult { - val dbCharacter: DbCharacter = - db.queryCharacter(characterId) ?: return QueryResult.NoCache - - return QueryResult.Successful(dbCharacter.toModelCharacter()) - } - - override suspend fun killCharacter(characterId: Int): QueryResult { - db.killCharacter(characterId) - return getCharacterDetails(characterId) - } - - companion object { - const val PAGE_SIZE: Int = 20 - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/ApiRickAndMorty.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/ApiRickAndMorty.kt deleted file mode 100644 index 3f9abcc..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/ApiRickAndMorty.kt +++ /dev/null @@ -1,107 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api - -import android.content.Context -import com.chuckerteam.chucker.api.ChuckerCollector -import com.chuckerteam.chucker.api.ChuckerInterceptor -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import com.mohsenoid.rickandmorty.BuildConfig -import com.mohsenoid.rickandmorty.data.api.mapper.ApiResultMapper.toApiResult -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisodes -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.json.Json -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import retrofit2.Response -import retrofit2.Retrofit -import retrofit2.http.GET -import retrofit2.http.Path -import retrofit2.http.Query -import java.net.UnknownHostException - -@OptIn(ExperimentalSerializationApi::class) -internal class ApiRickAndMorty(applicationContext: Context, baseUrl: String) { - - private val api = ApiClient.create(applicationContext, baseUrl) - - suspend fun fetchEpisodes(page: Int): ApiResult = - toApiResult { - api.fetchEpisodes(page) - } - - suspend fun fetchCharactersByIds(characterIds: String): ApiResult> = - toApiResult { - api.fetchCharactersByIds(characterIds) - } - - suspend fun fetchCharacterDetails(characterId: Int): ApiResult = - toApiResult { - api.fetchCharacterDetails(characterId) - } - - internal interface ApiClient { - - @GET(value = EPISODE_ENDPOINT) - suspend fun fetchEpisodes( - @Query(value = PARAM_KEY_PAGE) - page: Int, - ): Response - - @GET(value = "$CHARACTER_ENDPOINT{$PATH_KEY_CHARACTER_IDS}") - suspend fun fetchCharactersByIds( - @Path(value = PATH_KEY_CHARACTER_IDS) - characterIds: String, - ): Response> - - @GET(value = "$CHARACTER_ENDPOINT{$PATH_KEY_CHARACTER_ID}") - suspend fun fetchCharacterDetails( - @Path(value = PATH_KEY_CHARACTER_ID) - characterId: Int, - ): Response - - companion object { - private const val EPISODE_ENDPOINT: String = "episode/" - private const val CHARACTER_ENDPOINT: String = "character/" - - private const val PARAM_KEY_PAGE: String = "page" - - private const val PATH_KEY_CHARACTER_IDS: String = "characterIds" - private const val PATH_KEY_CHARACTER_ID: String = "characterId" - - internal fun create(applicationContext: Context, baseUrl: String): ApiClient { - val httpUrl = baseUrl.toHttpUrlOrNull() - ?: throw UnknownHostException("Invalid host: $baseUrl") - - val contentType = "application/json".toMediaType() - val converterFactory = Json.asConverterFactory(contentType) - - val loggerInterceptor = HttpLoggingInterceptor().apply { - level = HttpLoggingInterceptor.Level.BODY - } - - val chuckerInterceptor = ChuckerInterceptor.Builder(applicationContext) - .collector(ChuckerCollector(applicationContext)) - .build() - - val okHttpClient = OkHttpClient.Builder().apply { - val isDebug: Boolean = BuildConfig.DEBUG - if (isDebug) { - addInterceptor(loggerInterceptor) - } - addInterceptor(chuckerInterceptor) - }.build() - - val retrofit = Retrofit.Builder() - .baseUrl(httpUrl) - .addConverterFactory(converterFactory) - .client(okHttpClient) - .build() - - return retrofit.create(ApiClient::class.java) - } - } - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/mapper/ApiResultMapper.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/mapper/ApiResultMapper.kt deleted file mode 100644 index b9f8867..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/mapper/ApiResultMapper.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.mapper - -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import retrofit2.Response -import timber.log.Timber -import java.net.UnknownHostException - -object ApiResultMapper { - - private const val HTTP_CODE_400_BAD_REQUEST = 400 - private const val HTTP_CODE_401_UNAUTHORIZED = 401 - private const val HTTP_CODE_403_FORBIDDEN = 403 - private const val HTTP_CODE_503_SERVICE_UNAVAILABLE = 503 - - suspend inline fun toApiResult( - crossinline apiCall: suspend () -> Response, - ): ApiResult = kotlin.runCatching { - val response = apiCall() - if (response.isSuccessful) { - handleSuccessfulApiResponse(response) - } else { - handleErrorApiResponse(response) - } - }.getOrElse { throwable -> - Timber.e(throwable) - - when (throwable) { - is UnknownHostException -> ApiResult.Error.ServerError( - ApiResult.Error.ServerError.Reason.SERVER_UNREACHABLE, - ) - else -> ApiResult.Error.UnknownError(throwable) - } - } - - inline fun handleSuccessfulApiResponse(response: Response): ApiResult { - val body = response.body() - return when { - body != null -> ApiResult.Success(body) - else -> ApiResult.Error.UnknownError( - exception = IllegalStateException("response body is null"), - ) - } - } - - fun handleErrorApiResponse(response: Response<*>): ApiResult.Error.ServerError { - val reason = when (response.code()) { - HTTP_CODE_400_BAD_REQUEST -> ApiResult.Error.ServerError.Reason.BAD_REQUEST - HTTP_CODE_401_UNAUTHORIZED -> ApiResult.Error.ServerError.Reason.UNAUTHORIZED - HTTP_CODE_403_FORBIDDEN -> ApiResult.Error.ServerError.Reason.FORBIDDEN - HTTP_CODE_503_SERVICE_UNAVAILABLE -> ApiResult.Error.ServerError.Reason.SERVICE_UNAVAILABLE - else -> ApiResult.Error.ServerError.Reason.UNKNOWN - } - return ApiResult.Error.ServerError(reason = reason) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiCharacter.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiCharacter.kt deleted file mode 100644 index d2a89c1..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiCharacter.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiCharacter( - - @SerialName(value = "id") - val id: Int, - - @SerialName(value = "name") - val name: String, - - @SerialName(value = "status") - val status: String, - - @SerialName(value = "species") - val species: String, - - @SerialName(value = "type") - val type: String, - - @SerialName(value = "gender") - val gender: String, - - @SerialName(value = "origin") - val origin: ApiOrigin, - - @SerialName(value = "location") - val location: ApiLocation, - - @SerialName(value = "image") - val image: String, - - @SerialName(value = "episode") - val episodes: List, - - @SerialName(value = "url") - val url: String, - - @SerialName(value = "created") - val created: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisode.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisode.kt deleted file mode 100644 index b84f052..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisode.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiEpisode( - - @SerialName(value = "id") - val id: Int, - - @SerialName(value = "name") - val name: String, - - @SerialName(value = "air_date") - val airDate: String, - - @SerialName(value = "episode") - val episode: String, - - @SerialName(value = "characters") - val characters: List, - - @SerialName(value = "url") - val url: String, - - @SerialName(value = "created") - val created: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisodes.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisodes.kt deleted file mode 100644 index fef9b1e..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiEpisodes.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiEpisodes( - - @SerialName(value = "info") - val info: ApiInfo, - - @SerialName(value = "results") - val results: List, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiErrorResponse.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiErrorResponse.kt deleted file mode 100644 index ad9ce61..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiErrorResponse.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName - -data class ApiErrorResponse( - - @SerialName(value = "error") - val error: String? = null, - - @SerialName(value = "message") - val message: String? = null, - - @SerialName(value = "orgMessage") - val orgMessage: String? = null, - - @SerialName(value = "httpStatus") - val httpStatus: Int? = null, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiInfo.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiInfo.kt deleted file mode 100644 index b2e099a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiInfo.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiInfo( - - @SerialName(value = "count") - val count: Int, - - @SerialName(value = "pages") - val pages: Int, - - @SerialName(value = "next") - val next: String?, - - @SerialName(value = "prev") - val prev: String?, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiLocation.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiLocation.kt deleted file mode 100644 index c2e369a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiLocation.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiLocation( - - @SerialName(value = "name") - val name: String, - - @SerialName(value = "url") - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiOrigin.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiOrigin.kt deleted file mode 100644 index 7602f13..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiOrigin.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -internal data class ApiOrigin( - - @SerialName(value = "name") - val name: String, - - @SerialName(value = "url") - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiResult.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiResult.kt deleted file mode 100644 index 2a2c3d7..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/model/ApiResult.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api.model - -sealed class ApiResult { - - data class Success(val data: R) : ApiResult() - - sealed class Error : ApiResult() { - - data class ServerError(val reason: Reason) : Error() { - - enum class Reason { - UNAUTHORIZED, - BAD_REQUEST, - FORBIDDEN, - SERVICE_UNAVAILABLE, - SERVER_UNREACHABLE, - UNKNOWN - } - } - - data class UnknownError(val exception: Throwable) : Error() - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/module.kt deleted file mode 100644 index 8705d1f..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/api/module.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.mohsenoid.rickandmorty.data.api - -import com.mohsenoid.rickandmorty.util.KoinQualifiersNames -import kotlinx.serialization.ExperimentalSerializationApi -import org.koin.android.ext.koin.androidApplication -import org.koin.dsl.module - -@OptIn(ExperimentalSerializationApi::class) -val apiModule = module { - - single { - ApiRickAndMorty( - applicationContext = androidApplication(), - baseUrl = getProperty(KoinQualifiersNames.BASE_URL), - ) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMorty.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMorty.kt deleted file mode 100644 index 1b1c66d..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMorty.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import androidx.room.TypeConverters -import com.mohsenoid.rickandmorty.data.db.converters.DbTypeConverters -import com.mohsenoid.rickandmorty.data.db.dao.DbCharacterDaoAbs -import com.mohsenoid.rickandmorty.data.db.dao.DbEpisodeDao -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.data.db.model.DbLocation -import com.mohsenoid.rickandmorty.data.db.model.DbOrigin - -internal class DbRickAndMorty(context: Context) { - - private val db = Db.create(context) - - suspend fun insertEpisode(entityEpisode: DbEpisode) = - db.episodeDao.insertEpisode(entityEpisode) - - suspend fun queryAllEpisodes(): List = - db.episodeDao.queryAllEpisodes() - - suspend fun queryAllEpisodesByPage(page: Int, pageSize: Int): List = - db.episodeDao.queryAllEpisodesByPage(page, pageSize) - - suspend fun insertCharacter(character: DbCharacter) = - db.characterDao.insertCharacter(character) - - suspend fun queryCharactersByIds(characterIds: List): List = - db.characterDao.queryCharactersByIds(characterIds) - - suspend fun queryCharacter(characterId: Int): DbCharacter? = - db.characterDao.queryCharacter(characterId) - - suspend fun killCharacter(characterId: Int) = - db.characterDao.killCharacter(characterId) - - suspend fun insertOrUpdateCharacter(character: DbCharacter) = - db.characterDao.insertOrUpdateCharacter(character) - - @Database( - entities = [ - DbCharacter::class, - DbEpisode::class, - DbLocation::class, - DbOrigin::class, - ], - version = DATABASE_VERSION, - ) - @TypeConverters(DbTypeConverters::class) - internal abstract class Db : RoomDatabase() { - - abstract val episodeDao: DbEpisodeDao - - abstract val characterDao: DbCharacterDaoAbs - - companion object { - fun create(context: Context): Db { - return Room.databaseBuilder( - context, - Db::class.java, - DATABASE_NAME, - ) - .fallbackToDestructiveMigration() - .build() - } - } - } - - companion object { - private const val DATABASE_NAME: String = "rickandmorty.db" - private const val DATABASE_VERSION: Int = 5 - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/converters/DbTypeConverters.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/converters/DbTypeConverters.kt deleted file mode 100644 index 0a6011f..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/converters/DbTypeConverters.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.converters - -import androidx.room.TypeConverter -import com.mohsenoid.rickandmorty.data.db.model.DbLocation -import com.mohsenoid.rickandmorty.data.db.model.DbOrigin -import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.json.Json - -internal class DbTypeConverters { - - @TypeConverter - fun locationToJson(location: DbLocation?): String? { - return location?.let { Json.encodeToString(DbLocation.serializer(), it) } - } - - @TypeConverter - fun jsonToLocation(locationJson: String?): DbLocation? { - return locationJson?.let { Json.decodeFromString(DbLocation.serializer(), it) } - } - - @TypeConverter - fun originToJson(origin: DbOrigin?): String? { - return origin?.let { Json.encodeToString(DbOrigin.serializer(), it) } - } - - @TypeConverter - fun jsonToOrigin(originJson: String?): DbOrigin? { - return originJson?.let { Json.decodeFromString(DbOrigin.serializer(), it) } - } - - @TypeConverter - fun listOfIntToString(list: List?): String? { - return list?.let { Json.encodeToString(ListSerializer(Int.serializer()), it) } - } - - @TypeConverter - fun stringToListOfInt(string: String?): List? { - return string?.let { Json.decodeFromString(ListSerializer(Int.serializer()), it) } - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDao.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDao.kt deleted file mode 100644 index 0903eb5..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDao.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.dao - -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter - -internal interface DbCharacterDao { - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertCharacter(character: DbCharacter) - - @Query(value = "SELECT * FROM characters WHERE _id IN (:characterIds)") - suspend fun queryCharactersByIds(characterIds: List): List - - @Query(value = "SELECT * FROM characters WHERE _id = :characterId LIMIT 1") - suspend fun queryCharacter(characterId: Int): DbCharacter? - - @Query(value = "UPDATE characters SET is_killed_by_user = 1 WHERE _id = :characterId") - suspend fun killCharacter(characterId: Int) - - suspend fun insertOrUpdateCharacter(character: DbCharacter) -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDaoAbs.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDaoAbs.kt deleted file mode 100644 index 20fdfcc..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbCharacterDaoAbs.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.dao - -import androidx.room.Dao -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter - -@Dao -internal abstract class DbCharacterDaoAbs : DbCharacterDao { - - override suspend fun insertOrUpdateCharacter(character: DbCharacter) { - val oldCharacter: DbCharacter? = queryCharacter(characterId = character.id) - - insertCharacter( - character = if (oldCharacter != null) { - character.copy(isKilledByUser = oldCharacter.isKilledByUser) - } else { - character - }, - ) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbEpisodeDao.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbEpisodeDao.kt deleted file mode 100644 index 2c6034a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/dao/DbEpisodeDao.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode - -@Dao -internal interface DbEpisodeDao { - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertEpisode(entityEpisode: DbEpisode) - - @Query(value = "SELECT * FROM episodes") - suspend fun queryAllEpisodes(): List - - @Query(value = "SELECT * FROM episodes LIMIT :pageSize OFFSET (:page - 1) * :pageSize") - suspend fun queryAllEpisodesByPage(page: Int, pageSize: Int): List -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbCharacter.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbCharacter.kt deleted file mode 100644 index bb2bb75..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbCharacter.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.model - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.serialization.Serializable - -@Serializable -@Entity(tableName = "characters") -internal data class DbCharacter( - - @PrimaryKey - @ColumnInfo(name = "_id") - val id: Int, - - @ColumnInfo(name = "name") - val name: String, - - @ColumnInfo(name = "status") - val status: String, - - @ColumnInfo(name = "is_alive") - val isAlive: Boolean, - - @ColumnInfo(name = "species") - val species: String, - - @ColumnInfo(name = "type") - val type: String, - - @ColumnInfo(name = "gender") - val gender: String, - - @ColumnInfo(name = "origin") - val origin: DbOrigin, - - @ColumnInfo(name = "location") - val location: DbLocation, - - @ColumnInfo(name = "image") - val image: String, - - @ColumnInfo(name = "episode_ids") - val episodeIds: List, - - @ColumnInfo(name = "url") - val url: String, - - @ColumnInfo(name = "created") - val created: String, - - @ColumnInfo(name = "is_killed_by_user", defaultValue = "0") - val isKilledByUser: Boolean, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbEpisode.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbEpisode.kt deleted file mode 100644 index b0c18ab..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbEpisode.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.model - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.serialization.Serializable - -@Serializable -@Entity(tableName = "episodes") -internal data class DbEpisode( - - @PrimaryKey - @ColumnInfo(name = "_id") - val id: Int, - - @ColumnInfo(name = "name") - val name: String, - - @ColumnInfo(name = "air_date") - val airDate: String, - - @ColumnInfo(name = "episode") - val episode: String, - - @ColumnInfo(name = "character_ids") - val characterIds: List, - - @ColumnInfo(name = "url") - val url: String, - - @ColumnInfo(name = "created") - val created: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbLocation.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbLocation.kt deleted file mode 100644 index b020611..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbLocation.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.model - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.serialization.Serializable - -@Serializable -@Entity(tableName = "locations") -internal data class DbLocation( - - @PrimaryKey - @ColumnInfo(name = "name") - val name: String, - - @ColumnInfo(name = "url") - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbOrigin.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbOrigin.kt deleted file mode 100644 index 7ea1d67..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/model/DbOrigin.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db.model - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.serialization.Serializable - -@Serializable -@Entity(tableName = "origins") -internal data class DbOrigin( - - @PrimaryKey - @ColumnInfo(name = "name") - val name: String, - - @ColumnInfo(name = "url") - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/module.kt deleted file mode 100644 index 87e4c0a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/db/module.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db - -import org.koin.core.annotation.KoinReflectAPI -import org.koin.dsl.module -import org.koin.dsl.single - -@OptIn(KoinReflectAPI::class) -val dbModule = module { - single() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapper.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapper.kt deleted file mode 100644 index 52a5a43..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapper.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.mohsenoid.rickandmorty.data.mapper - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiLocation -import com.mohsenoid.rickandmorty.data.api.model.ApiOrigin -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbLocation -import com.mohsenoid.rickandmorty.data.db.model.DbOrigin -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.domain.model.ModelLocation -import com.mohsenoid.rickandmorty.domain.model.ModelOrigin - -private const val DEAD: String = "dead" - -private const val SEPARATOR: Char = '/' - -internal fun extractEpisodeIds(episodes: List): List { - return episodes.map { it.split(SEPARATOR).last().toInt() } -} - -internal fun ApiCharacter.toDbCharacter() = - DbCharacter( - id = id, - name = name, - status = status, - isAlive = !status.equals(DEAD, ignoreCase = true), - species = species, - type = type, - gender = gender, - origin = origin.toDbOrigin(), - location = location.toDbLocation(), - image = image, - episodeIds = extractEpisodeIds(episodes), - url = url, - created = created, - isKilledByUser = false, - ) - -private fun ApiOrigin.toDbOrigin() = - DbOrigin( - name = name, - url = url, - ) - -private fun ApiLocation.toDbLocation() = - DbLocation( - name = name, - url = url, - ) - -internal fun DbCharacter.toModelCharacter() = - ModelCharacter( - id = id, - name = name, - status = status, - isAlive = isAlive, - species = species, - type = type, - gender = gender, - origin = origin.toModelOrigin(), - location = location.toModelLocation(), - imageUrl = image, - episodeIds = episodeIds, - url = url, - created = created, - isKilledByUser = isKilledByUser, - ) - -private fun DbOrigin.toModelOrigin() = - ModelOrigin( - name = name, - url = url, - ) - -private fun DbLocation.toModelLocation() = - ModelLocation( - name = name, - url = url, - ) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapper.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapper.kt deleted file mode 100644 index 1c3fe3b..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapper.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.mohsenoid.rickandmorty.data.mapper - -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisode -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode - -private const val SEPARATOR: Char = '/' - -internal fun extractCharacterIds(characters: List): List { - return characters.map { it.split(SEPARATOR).last().toInt() } -} - -internal fun ApiEpisode.toDbEpisode() = - DbEpisode( - id = id, - name = name, - airDate = airDate, - episode = episode, - characterIds = extractCharacterIds(characters), - url = url, - created = created, - ) - -internal fun DbEpisode.toModelEpisode() = - ModelEpisode( - id = id, - name = name, - airDate = airDate, - episode = episode, - characterIds = characterIds, - url = url, - created = created, - ) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/module.kt deleted file mode 100644 index a07587e..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/data/module.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.apiModule -import com.mohsenoid.rickandmorty.data.db.dbModule -import com.mohsenoid.rickandmorty.domain.Repository -import org.koin.dsl.module - -val dataModule = dbModule + apiModule + module { - - single { - RepositoryImpl( - db = get(), - api = get(), - statusProvider = get(), - ) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/Repository.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/Repository.kt deleted file mode 100644 index e92aaaa..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/Repository.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.mohsenoid.rickandmorty.domain - -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode -import com.mohsenoid.rickandmorty.domain.model.PageQueryResult -import com.mohsenoid.rickandmorty.domain.model.QueryResult - -interface Repository { - - suspend fun getEpisodes(page: Int): PageQueryResult> - - suspend fun getCharactersByIds(characterIds: List): QueryResult> - - suspend fun getCharacterDetails(characterId: Int): QueryResult - - suspend fun killCharacter(characterId: Int): QueryResult -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelCharacter.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelCharacter.kt deleted file mode 100644 index 06d7ed2..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelCharacter.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -data class ModelCharacter( - val id: Int, - val name: String, - val status: String, - val isAlive: Boolean, - val species: String, - val type: String, - val gender: String, - val origin: ModelOrigin, - val location: ModelLocation, - val imageUrl: String, - val episodeIds: List, - val url: String, - val created: String, - val isKilledByUser: Boolean, -) { - - val isAliveAndNotKilledByUser: Boolean - get() = isAlive && !isKilledByUser -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelEpisode.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelEpisode.kt deleted file mode 100644 index 70a3140..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelEpisode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -data class ModelEpisode( - val id: Int, - val name: String, - val airDate: String, - val episode: String, - val characterIds: List, - val url: String, - val created: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelLocation.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelLocation.kt deleted file mode 100644 index f01deab..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelLocation.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -data class ModelLocation( - val name: String, - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelOrigin.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelOrigin.kt deleted file mode 100644 index ed5fb7d..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/ModelOrigin.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -data class ModelOrigin( - val name: String, - val url: String, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/PageQueryResult.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/PageQueryResult.kt deleted file mode 100644 index 315d28a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/PageQueryResult.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -sealed interface PageQueryResult { - data class Successful(val data: T) : PageQueryResult - object EndOfList : PageQueryResult - object Error : PageQueryResult -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/QueryResult.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/QueryResult.kt deleted file mode 100644 index 3afbc60..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/domain/model/QueryResult.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mohsenoid.rickandmorty.domain.model - -sealed interface QueryResult { - data class Successful(val data: T) : QueryResult - object NoCache : QueryResult - object Error : QueryResult -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/module.kt deleted file mode 100644 index 94d307f..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/module.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.mohsenoid.rickandmorty - -import com.mohsenoid.rickandmorty.util.StatusProvider -import com.mohsenoid.rickandmorty.util.StatusProviderImpl -import org.koin.android.ext.koin.androidContext -import org.koin.dsl.module - -val appModule = module { - single { StatusProviderImpl(context = androidContext()) } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/startup/TimberInitializer.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/startup/TimberInitializer.kt deleted file mode 100644 index 1927ffe..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/startup/TimberInitializer.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.mohsenoid.rickandmorty.startup - -import android.content.Context -import androidx.startup.Initializer -import com.mohsenoid.rickandmorty.BuildConfig -import timber.log.Timber - -class TimberInitializer : Initializer { - - private val isDebug: Boolean = BuildConfig.DEBUG - - override fun create(context: Context) { - if (isDebug) setupTimber() - } - - private fun setupTimber() { - Timber.plant( - object : Timber.DebugTree() { - override fun createStackElementTag(element: StackTraceElement): String { - // adding file name and line number link to logs - return "${super.createStackElementTag(element)}(${element.fileName}:${element.lineNumber})" - } - }, - ) - } - - override fun dependencies(): MutableList>> = mutableListOf() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/KoinQualifiersNames.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/KoinQualifiersNames.kt deleted file mode 100644 index 4c447e2..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/KoinQualifiersNames.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.mohsenoid.rickandmorty.util - -object KoinQualifiersNames { - const val BASE_URL = "baseUrl" -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProvider.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProvider.kt deleted file mode 100644 index 4ed9e8f..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProvider.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.mohsenoid.rickandmorty.util - -/** - * Application Status Provider. - */ -interface StatusProvider { - - /** - * Checks network connectivity status. - */ - fun isOnline(): Boolean -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProviderImpl.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProviderImpl.kt deleted file mode 100644 index 13d33cb..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/util/StatusProviderImpl.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.mohsenoid.rickandmorty.util - -import android.content.Context -import android.net.ConnectivityManager -import android.net.Network -import android.net.NetworkCapabilities - -/** - * - * This class implements [StatusProvider] and provides configurations required on runtime. - * - * @constructor Creates a ConfigProvider using the Android Application context. - * @param context the Android Application context. - */ -class StatusProviderImpl(private val context: Context) : StatusProvider { - - /** - * This function uses [ConnectivityManager] to check active Network Capabilities to know - * the Android phone network connectivity status. - * - * @return is the phone connected to a network through cellular or WiFi. - */ - @Suppress("ReturnCount") - override fun isOnline(): Boolean { - val connectivityManager: ConnectivityManager = - context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager - ?: return false - - val activeNetwork: Network = connectivityManager.activeNetwork ?: return false - - val networkCapabilities: NetworkCapabilities = - connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false - - return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || - networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || - networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/MainActivity.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/MainActivity.kt deleted file mode 100644 index fa454c7..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/MainActivity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.mohsenoid.rickandmorty.view - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.mohsenoid.rickandmorty.R - -class MainActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsFragment.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsFragment.kt deleted file mode 100644 index 66b474c..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsFragment.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.details - -import android.app.Activity -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.navArgs -import com.mohsenoid.rickandmorty.R -import com.mohsenoid.rickandmorty.databinding.FragmentCharacterDetailsBinding -import com.mohsenoid.rickandmorty.view.util.launchWhileResumed -import kotlinx.coroutines.flow.collectLatest -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.context.loadKoinModules -import org.koin.core.context.unloadKoinModules -import org.koin.core.parameter.parametersOf - -@Suppress("TooManyFunctions") -class CharacterDetailsFragment : Fragment() { - - private var _binding: FragmentCharacterDetailsBinding? = null - private val binding get() = _binding!! - - private val args: CharacterDetailsFragmentArgs by navArgs() - - private val viewModel: CharacterDetailsViewModel by viewModel { - parametersOf(args.characterId) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - loadKoinModules(characterDetailsFragmentModule) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - _binding = FragmentCharacterDetailsBinding.inflate(inflater, container, false) - binding.lifecycleOwner = viewLifecycleOwner - binding.viewModel = viewModel - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - lifecycle.launchWhileResumed { - viewModel.onError.collectLatest { - if (it) showErrorMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isOffline.collectLatest { - if (it) showOfflineMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isNoCache.collectLatest { - if (it) onNoOfflineData() - } - } - } - - private fun showErrorMessage() { - Toast.makeText(context, R.string.error_message, Toast.LENGTH_LONG).show() - } - - private fun showOfflineMessage() { - Toast.makeText(context, R.string.offline_app, Toast.LENGTH_LONG).show() - } - - private fun onNoOfflineData() { - Toast.makeText(context, R.string.no_offline_data, Toast.LENGTH_LONG).show() - parentActivityOnBackPressed() - } - - private fun parentActivityOnBackPressed() { - val parentActivity: Activity? = activity - parentActivity?.onBackPressed() - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - override fun onDestroy() { - unloadKoinModules(characterDetailsFragmentModule) - super.onDestroy() - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsViewModel.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsViewModel.kt deleted file mode 100644 index b748581..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/CharacterDetailsViewModel.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.details - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mohsenoid.rickandmorty.domain.Repository -import com.mohsenoid.rickandmorty.domain.model.QueryResult -import com.mohsenoid.rickandmorty.util.StatusProvider -import com.mohsenoid.rickandmorty.view.mapper.toViewCharacterDetails -import com.mohsenoid.rickandmorty.view.model.LoadingState -import com.mohsenoid.rickandmorty.view.model.ViewCharacterDetails -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch - -class CharacterDetailsViewModel( - private val characterId: Int, - private val repository: Repository, - private val statusProvider: StatusProvider, -) : ViewModel() { - - private val _loadingState: MutableStateFlow = MutableStateFlow(LoadingState.None) - val loadingState: StateFlow = _loadingState - - private val _isOffline: MutableStateFlow = MutableStateFlow(false) - val isOffline: StateFlow = _isOffline - - private val _isNoCache: MutableStateFlow = MutableStateFlow(false) - val isNoCache: StateFlow = _isNoCache - - private val _onError: MutableStateFlow = MutableStateFlow(false) - val onError: StateFlow = _onError - - private val _character: MutableStateFlow = MutableStateFlow(null) - val character: StateFlow = _character - - init { - loadCharacter() - } - - private fun loadCharacter() { - _loadingState.value = LoadingState.Loading - _onError.value = false - _isNoCache.value = false - _isOffline.value = false - queryCharacter() - } - - private fun queryCharacter() { - if (!statusProvider.isOnline()) { - _isOffline.value = true - } - - viewModelScope.launch { - when (val result = repository.getCharacterDetails(characterId)) { - is QueryResult.Successful -> _character.value = result.data.toViewCharacterDetails() - QueryResult.NoCache -> _isNoCache.value = true - QueryResult.Error -> _onError.value = true - } - - _loadingState.value = LoadingState.None - } - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/module.kt deleted file mode 100644 index fb983ec..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/details/module.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.details - -import org.koin.androidx.viewmodel.dsl.viewModel -import org.koin.dsl.module - -val characterDetailsFragmentModule = module { - - viewModel { (characterId: Int) -> - CharacterDetailsViewModel( - characterId = characterId, - repository = get(), - statusProvider = get(), - ) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListFragment.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListFragment.kt deleted file mode 100644 index 83a8c61..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListFragment.kt +++ /dev/null @@ -1,104 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.list - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.navigation.findNavController -import androidx.navigation.fragment.navArgs -import com.mohsenoid.rickandmorty.R -import com.mohsenoid.rickandmorty.databinding.FragmentCharacterListBinding -import com.mohsenoid.rickandmorty.view.util.launchWhileResumed -import kotlinx.coroutines.flow.collectLatest -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.context.loadKoinModules -import org.koin.core.context.unloadKoinModules -import org.koin.core.parameter.parametersOf - -@Suppress("TooManyFunctions") -class CharacterListFragment : Fragment() { - - private var _binding: FragmentCharacterListBinding? = null - private val binding get() = _binding!! - - private val args: CharacterListFragmentArgs by navArgs() - - private val viewModel: CharacterListViewModel by viewModel { - parametersOf(args.characterIds.toList()) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - loadKoinModules(characterListFragmentModule) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - _binding = FragmentCharacterListBinding.inflate(inflater, container, false) - binding.lifecycleOwner = viewLifecycleOwner - binding.viewModel = viewModel - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - lifecycle.launchWhileResumed { - viewModel.onError.collectLatest { - if (it) showErrorMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isOffline.collectLatest { - if (it) showOfflineMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isNoCache.collectLatest { - if (it) onNoOfflineData() - } - } - - lifecycle.launchWhileResumed { - viewModel.selectedCharacterId.collectLatest { characterId -> - onCharacterRowClick(characterId) - } - } - } - - private fun showErrorMessage() { - Toast.makeText(context, R.string.error_message, Toast.LENGTH_LONG).show() - } - - private fun showOfflineMessage() { - Toast.makeText(context, R.string.offline_app, Toast.LENGTH_LONG).show() - } - - private fun onNoOfflineData() { - Toast.makeText(context, R.string.no_offline_data, Toast.LENGTH_LONG).show() - activity?.onBackPressed() - } - - fun onCharacterRowClick(characterId: Int) { - val action = CharacterListFragmentDirections - .actionCharacterListFragmentToCharacterDetailsFragment(characterId) - view?.findNavController()?.navigate(action) - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - override fun onDestroy() { - unloadKoinModules(characterListFragmentModule) - super.onDestroy() - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListViewModel.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListViewModel.kt deleted file mode 100644 index 72ec3b8..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/CharacterListViewModel.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.list - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mohsenoid.rickandmorty.domain.Repository -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.domain.model.QueryResult -import com.mohsenoid.rickandmorty.util.StatusProvider -import com.mohsenoid.rickandmorty.view.mapper.toViewCharacterItem -import com.mohsenoid.rickandmorty.view.model.LoadingState -import com.mohsenoid.rickandmorty.view.model.ViewCharacterItem -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.launch - -class CharacterListViewModel( - private val characterIds: List, - private val repository: Repository, - private val statusProvider: StatusProvider, -) : ViewModel() { - - private val _loadingState: MutableStateFlow = MutableStateFlow(LoadingState.None) - val loadingState: StateFlow = _loadingState - - private val _isOffline: MutableStateFlow = MutableStateFlow(false) - val isOffline: StateFlow = _isOffline - - private val _isNoCache: MutableStateFlow = MutableStateFlow(false) - val isNoCache: StateFlow = _isNoCache - - private val _onError: MutableStateFlow = MutableStateFlow(false) - val onError: StateFlow = _onError - - private val _characters: MutableStateFlow> = - MutableStateFlow(mutableListOf()) - val characters: StateFlow> = _characters - - private val _selectedCharacterId: Channel = Channel() - val selectedCharacterId: Flow = _selectedCharacterId.receiveAsFlow() - - init { - loadCharacters() - } - - private fun loadCharacters() { - _loadingState.value = LoadingState.Loading - _onError.value = false - _isNoCache.value = false - _isOffline.value = false - queryCharacters() - } - - private fun queryCharacters() { - if (!statusProvider.isOnline()) { - _isOffline.value = true - } - - viewModelScope.launch { - when (val result = repository.getCharactersByIds(characterIds)) { - is QueryResult.Successful -> _characters.value = result.data.toViewCharacterItems() - QueryResult.NoCache -> _isNoCache.value = true - QueryResult.Error -> _onError.value = true - } - - _loadingState.value = LoadingState.None - } - } - - private fun killCharacter(character: ModelCharacter) { - if (!character.isAliveAndNotKilledByUser) return - - if (!statusProvider.isOnline()) { - _isOffline.value = true - } - - viewModelScope.launch { - when (repository.killCharacter(character.id)) { - is QueryResult.Successful -> { - queryCharacters() - } - QueryResult.NoCache -> _isNoCache.value = true - QueryResult.Error -> _onError.value = true - } - } - } - - private fun List.toViewCharacterItems(): MutableList = - map { character -> - character.toViewCharacterItem( - onKill = { - killCharacter(character) - }, - onClick = { - _selectedCharacterId.trySend(character.id) - }, - ) - }.toMutableList() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterListAdapter.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterListAdapter.kt deleted file mode 100644 index 4dc014d..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterListAdapter.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.list.adapter - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import com.mohsenoid.rickandmorty.databinding.ItemCharacterBinding -import com.mohsenoid.rickandmorty.view.model.ViewCharacterItem -import java.util.ArrayList - -class CharacterListAdapter : RecyclerView.Adapter() { - - private var characters: MutableList = ArrayList() - - @SuppressLint("NotifyDataSetChanged") - fun setCharacters(characters: List) { - this.characters = characters.toMutableList() - notifyDataSetChanged() - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharacterViewHolder { - val binding = - ItemCharacterBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return CharacterViewHolder(binding) - } - - override fun onBindViewHolder(holder: CharacterViewHolder, position: Int) { - val character: ViewCharacterItem = characters[position] - holder.setCharacter(character) - } - - override fun getItemCount(): Int { - return characters.size - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterViewHolder.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterViewHolder.kt deleted file mode 100644 index 33556c1..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/adapter/CharacterViewHolder.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.list.adapter - -import androidx.recyclerview.widget.RecyclerView.ViewHolder -import com.mohsenoid.rickandmorty.databinding.ItemCharacterBinding -import com.mohsenoid.rickandmorty.view.model.ViewCharacterItem - -class CharacterViewHolder internal constructor( - internal val binding: ItemCharacterBinding, -) : ViewHolder(binding.root) { - - fun setCharacter(character: ViewCharacterItem) { - binding.character = character - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/module.kt deleted file mode 100644 index e6a621c..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/character/list/module.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mohsenoid.rickandmorty.view.character.list - -import org.koin.androidx.viewmodel.dsl.viewModel -import org.koin.dsl.module - -val characterListFragmentModule = module { - - viewModel { (characterIds: List) -> - CharacterListViewModel( - characterIds = characterIds, - repository = get(), - statusProvider = get(), - ) - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListFragment.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListFragment.kt deleted file mode 100644 index 474a1e7..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListFragment.kt +++ /dev/null @@ -1,113 +0,0 @@ -package com.mohsenoid.rickandmorty.view.episode.list - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.navigation.findNavController -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.mohsenoid.rickandmorty.R -import com.mohsenoid.rickandmorty.databinding.FragmentEpisodeListBinding -import com.mohsenoid.rickandmorty.view.util.EndlessRecyclerViewScrollListener -import com.mohsenoid.rickandmorty.view.util.launchWhileResumed -import kotlinx.coroutines.flow.collectLatest -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.context.loadKoinModules -import org.koin.core.context.unloadKoinModules - -@Suppress("TooManyFunctions") -class EpisodeListFragment : Fragment() { - - private var _binding: FragmentEpisodeListBinding? = null - private val binding get() = _binding!! - - private val viewModel: EpisodeListViewModel by viewModel() - - private var endlessScrollListener: EndlessRecyclerViewScrollListener? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - loadKoinModules(episodeListFragmentModule) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - _binding = FragmentEpisodeListBinding.inflate(inflater, container, false) - binding.lifecycleOwner = viewLifecycleOwner - binding.viewModel = viewModel - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val linearLayoutManager = LinearLayoutManager(context) - binding.episodeList.layoutManager = linearLayoutManager - endlessScrollListener = object : EndlessRecyclerViewScrollListener(linearLayoutManager) { - override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) { - viewModel.loadMoreEpisodes(page = page + 1) - } - }.also { - binding.episodeList.addOnScrollListener(it) - } - - lifecycle.launchWhileResumed { - viewModel.onError.collectLatest { - if (it) showErrorMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isOffline.collectLatest { - if (it) showOfflineMessage() - } - } - - lifecycle.launchWhileResumed { - viewModel.isEndOfList.collectLatest { - if (it) reachedEndOfList() - } - } - - lifecycle.launchWhileResumed { - viewModel.selectedEpisodeCharacterIds.collectLatest { characterIds -> - onEpisodeRowClick(characterIds) - } - } - } - - private fun showErrorMessage() { - Toast.makeText(context, R.string.error_message, Toast.LENGTH_LONG).show() - } - - private fun showOfflineMessage() { - Toast.makeText(context, R.string.offline_app, Toast.LENGTH_SHORT).show() - } - - private fun reachedEndOfList() { - binding.episodeListProgress.visibility = View.GONE - } - - private fun onEpisodeRowClick(characterIds: IntArray) { - val action = EpisodeListFragmentDirections - .actionEpisodeListFragmentToCharacterListFragment(characterIds) - view?.findNavController()?.navigate(action) - } - - override fun onDestroyView() { - super.onDestroyView() - endlessScrollListener = null - _binding = null - } - - override fun onDestroy() { - unloadKoinModules(episodeListFragmentModule) - super.onDestroy() - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListViewModel.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListViewModel.kt deleted file mode 100644 index f343f46..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/EpisodeListViewModel.kt +++ /dev/null @@ -1,92 +0,0 @@ -package com.mohsenoid.rickandmorty.view.episode.list - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mohsenoid.rickandmorty.domain.Repository -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode -import com.mohsenoid.rickandmorty.domain.model.PageQueryResult -import com.mohsenoid.rickandmorty.util.StatusProvider -import com.mohsenoid.rickandmorty.view.mapper.toViewEpisodeItem -import com.mohsenoid.rickandmorty.view.model.LoadingState -import com.mohsenoid.rickandmorty.view.model.ViewEpisodeItem -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.launch - -class EpisodeListViewModel( - private val repository: Repository, - private val statusProvider: StatusProvider, -) : ViewModel() { - - private val _loadingState: MutableStateFlow = MutableStateFlow(LoadingState.None) - val loadingState: StateFlow = _loadingState - - private val _isOffline: MutableStateFlow = MutableStateFlow(false) - val isOffline: StateFlow = _isOffline - - private val _isEndOfList: MutableStateFlow = MutableStateFlow(false) - val isEndOfList: StateFlow = _isEndOfList - - private val _onError: MutableStateFlow = MutableStateFlow(false) - val onError: StateFlow = _onError - - private val _episodes: MutableStateFlow> = MutableStateFlow(emptyList()) - val episodes: StateFlow> = _episodes - - private val _selectedEpisodeCharacterIds: Channel = Channel() - val selectedEpisodeCharacterIds: Flow = _selectedEpisodeCharacterIds.receiveAsFlow() - - private var page = 1 - - init { - loadEpisodes() - } - - fun loadEpisodes() { - _loadingState.value = LoadingState.Loading - _isEndOfList.value = false - _onError.value = false - _isOffline.value = false - page = 1 - getEpisodes() - } - - fun loadMoreEpisodes(page: Int) { - _loadingState.value = LoadingState.LoadingMore - this.page = page - getEpisodes() - } - - private fun getEpisodes() { - if (!statusProvider.isOnline()) { - _isOffline.value = true - } - - viewModelScope.launch { - when (val result = repository.getEpisodes(page)) { - is PageQueryResult.Successful -> { - if (page == 1) { - _episodes.value = - result.data.toViewEpisodeItems() - } else { - _episodes.value = _episodes.value + result.data.toViewEpisodeItems() - } - } - PageQueryResult.EndOfList -> _isEndOfList.value = true - PageQueryResult.Error -> _onError.value = true - } - - _loadingState.value = LoadingState.None - } - } - - private fun List.toViewEpisodeItems(): List = - map { episode -> - episode.toViewEpisodeItem { - _selectedEpisodeCharacterIds.trySend(episode.characterIds.toIntArray()) - } - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeListAdapter.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeListAdapter.kt deleted file mode 100644 index 94b7859..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeListAdapter.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mohsenoid.rickandmorty.view.episode.list.adapter - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import com.mohsenoid.rickandmorty.databinding.ItemEpisodeBinding -import com.mohsenoid.rickandmorty.view.model.ViewEpisodeItem -import java.util.ArrayList - -class EpisodeListAdapter : - RecyclerView.Adapter() { - - private var episodes: MutableList = ArrayList() - - @SuppressLint("NotifyDataSetChanged") - fun setEpisodes(episodes: List) { - this.episodes = episodes.toMutableList() - notifyDataSetChanged() - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpisodeViewHolder { - val binding = ItemEpisodeBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return EpisodeViewHolder(binding) - } - - override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) { - val episode: ViewEpisodeItem = episodes[position] - holder.setEpisode(episode) - } - - override fun getItemCount(): Int { - return episodes.size - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeViewHolder.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeViewHolder.kt deleted file mode 100644 index d4e7981..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/adapter/EpisodeViewHolder.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.mohsenoid.rickandmorty.view.episode.list.adapter - -import androidx.recyclerview.widget.RecyclerView.ViewHolder -import com.mohsenoid.rickandmorty.databinding.ItemEpisodeBinding -import com.mohsenoid.rickandmorty.view.model.ViewEpisodeItem - -class EpisodeViewHolder internal constructor(internal val binding: ItemEpisodeBinding) : - ViewHolder(binding.root) { - - fun setEpisode(episode: ViewEpisodeItem) { - binding.episode = episode - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/module.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/module.kt deleted file mode 100644 index 415d7d4..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/episode/list/module.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mohsenoid.rickandmorty.view.episode.list - -import org.koin.androidx.viewmodel.dsl.viewModel -import org.koin.core.annotation.KoinReflectAPI -import org.koin.dsl.module - -@OptIn(KoinReflectAPI::class) -val episodeListFragmentModule = module { - - viewModel() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/CharacterMapper.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/CharacterMapper.kt deleted file mode 100644 index 6d52806..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/CharacterMapper.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mohsenoid.rickandmorty.view.mapper - -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.view.model.ViewCharacterDetails -import com.mohsenoid.rickandmorty.view.model.ViewCharacterItem - -fun ModelCharacter.toViewCharacterItem(onKill: () -> Unit, onClick: () -> Unit) = ViewCharacterItem( - name = name, - imageUrl = imageUrl, - isAliveAndNotKilledByUser = isAliveAndNotKilledByUser, - onKill = onKill, - onClick = onClick, -) - -fun ModelCharacter.toViewCharacterDetails() = ViewCharacterDetails( - id = id, - name = name, - status = status, - species = species, - gender = gender, - origin = origin.name, - location = location.name, - imageUrl = imageUrl, - created = created, - isKilledByUser = isKilledByUser, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/EpisodeMapper.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/EpisodeMapper.kt deleted file mode 100644 index f199d72..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/mapper/EpisodeMapper.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mohsenoid.rickandmorty.view.mapper - -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode -import com.mohsenoid.rickandmorty.view.model.ViewEpisodeItem - -fun ModelEpisode.toViewEpisodeItem(onClick: () -> Unit) = ViewEpisodeItem( - name = name, - airDate = airDate, - episode = episode, - onClick = onClick, -) diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/LoadingState.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/LoadingState.kt deleted file mode 100644 index d96f823..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/LoadingState.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mohsenoid.rickandmorty.view.model - -sealed interface LoadingState { - object None : LoadingState - object Loading : LoadingState - object LoadingMore : LoadingState -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterItem.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterItem.kt deleted file mode 100644 index eb3e00a..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterItem.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.mohsenoid.rickandmorty.view.model - -data class ViewCharacterItem( - val name: String, - val imageUrl: String, - val isAliveAndNotKilledByUser: Boolean, - val onKill: () -> Unit, - val onClick: () -> Unit, -) { - fun onKill() = onKill.invoke() - fun onClick() = onClick.invoke() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewEpisodeItem.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewEpisodeItem.kt deleted file mode 100644 index 41b39ab..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewEpisodeItem.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.mohsenoid.rickandmorty.view.model - -data class ViewEpisodeItem( - val name: String, - val airDate: String, - val episode: String, - val onClick: () -> Unit, -) { - fun onClick() = onClick.invoke() -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/BindingAdapters.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/BindingAdapters.kt deleted file mode 100644 index 6effd20..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/BindingAdapters.kt +++ /dev/null @@ -1,80 +0,0 @@ -package com.mohsenoid.rickandmorty.view.util - -import android.view.View -import android.widget.ImageView -import android.widget.ProgressBar -import androidx.databinding.BindingAdapter -import androidx.recyclerview.widget.RecyclerView -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import com.mohsenoid.rickandmorty.R -import com.mohsenoid.rickandmorty.view.character.list.adapter.CharacterListAdapter -import com.mohsenoid.rickandmorty.view.episode.list.adapter.EpisodeListAdapter -import com.mohsenoid.rickandmorty.view.model.LoadingState -import com.mohsenoid.rickandmorty.view.model.ViewCharacterItem -import com.mohsenoid.rickandmorty.view.model.ViewEpisodeItem -import com.squareup.picasso.Picasso - -@BindingAdapter("visibility") -fun View.setVisibility(isVisible: Boolean) { - visibility = if (isVisible) View.VISIBLE else View.GONE -} - -@BindingAdapter("onRefreshListener") -fun SwipeRefreshLayout.onRefreshListener(listener: SwipeRefreshLayout.OnRefreshListener?) { - setOnRefreshListener(listener) -} - -@BindingAdapter("isRefreshing") -fun SwipeRefreshLayout.setIsRefreshing(loadingState: LoadingState?) { - isRefreshing = loadingState == LoadingState.Loading -} - -@BindingAdapter("isLoading") -fun ProgressBar.setIsLoading(loadingState: LoadingState?) { - visibility = if (loadingState == LoadingState.Loading) View.VISIBLE else View.GONE -} - -@BindingAdapter("isLoadingMore") -fun ProgressBar.setIsLoadingMore(loadingState: LoadingState?) { - visibility = if (loadingState == LoadingState.LoadingMore) View.VISIBLE else View.GONE -} - -@BindingAdapter("episodes") -fun RecyclerView.setEpisodes(itemViewModels: List?) { - val adapter = getOrCreateEpisodeListAdapter() - adapter.setEpisodes(itemViewModels ?: emptyList()) -} - -private fun RecyclerView.getOrCreateEpisodeListAdapter(): EpisodeListAdapter { - return if (adapter != null && adapter is EpisodeListAdapter) { - adapter as EpisodeListAdapter - } else { - val newAdapter = EpisodeListAdapter() - adapter = newAdapter - newAdapter - } -} - -@BindingAdapter("characters") -fun RecyclerView.setCharacters(itemViewModels: List?) { - val adapter = getOrCreateCharacterListAdapter() - adapter.setCharacters(itemViewModels ?: emptyList()) -} - -private fun RecyclerView.getOrCreateCharacterListAdapter(): CharacterListAdapter { - return if (adapter != null && adapter is CharacterListAdapter) { - adapter as CharacterListAdapter - } else { - val newAdapter = CharacterListAdapter() - adapter = newAdapter - newAdapter - } -} - -@BindingAdapter("imageUrl") -fun ImageView.setImageUrl(imageUrl: String?) { - Picasso.get() - .load(imageUrl) - .placeholder(R.drawable.ic_placeholder) - .into(this) -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/EndlessRecyclerViewScrollListener.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/EndlessRecyclerViewScrollListener.kt deleted file mode 100644 index a1ff170..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/EndlessRecyclerViewScrollListener.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.mohsenoid.rickandmorty.view.util - -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView - -abstract class EndlessRecyclerViewScrollListener(private val layoutManager: LinearLayoutManager) : - RecyclerView.OnScrollListener() { - - private var visibleThreshold = DEFAULT_VISIBLE_THRESHOLD - private var currentPage = 0 - private var previousTotalItemCount = 0 - private var loading = true - private val startingPageIndex = 0 - - override fun onScrolled(view: RecyclerView, dx: Int, dy: Int) { - val totalItemCount: Int = layoutManager.itemCount - val lastVisibleItemPosition: Int = layoutManager.findLastVisibleItemPosition() - - if (totalItemCount < previousTotalItemCount) { - currentPage = startingPageIndex - previousTotalItemCount = totalItemCount - if (totalItemCount == 0) { - loading = true - } - } - if (loading && totalItemCount > previousTotalItemCount) { - loading = false - previousTotalItemCount = totalItemCount - } - if (!loading && lastVisibleItemPosition + visibleThreshold > totalItemCount) { - currentPage++ - onLoadMore(currentPage, totalItemCount, view) - loading = true - } - } - - fun resetState() { - currentPage = startingPageIndex - previousTotalItemCount = 0 - loading = true - } - - abstract fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) - - companion object { - const val DEFAULT_VISIBLE_THRESHOLD = 5 - } -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/LifecycleExtensions.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/LifecycleExtensions.kt deleted file mode 100644 index 2028bb8..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/LifecycleExtensions.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.mohsenoid.rickandmorty.view.util - -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.coroutineScope -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job - -fun Lifecycle.launchWhileResumed(block: suspend CoroutineScope.() -> Unit): Job { - val job = coroutineScope.launchWhenResumed(block) - addObserver( - object : DefaultLifecycleObserver { - override fun onPause(owner: LifecycleOwner) { - job.cancel() - removeObserver(this) - } - }, - ) - return job -} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/SquareImageView.kt b/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/SquareImageView.kt deleted file mode 100644 index 95e71cd..0000000 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/util/SquareImageView.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.mohsenoid.rickandmorty.view.util - -import android.content.Context -import android.util.AttributeSet -import androidx.appcompat.widget.AppCompatImageView - -class SquareImageView : AppCompatImageView { - - constructor(context: Context) : super(context) - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( - context, - attrs, - defStyleAttr, - ) - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec) - val width: Int = measuredWidth - setMeasuredDimension(width, width) - } -} diff --git a/app/src/main/res/drawable/ic_alive.xml b/app/src/main/res/drawable/ic_alive.xml deleted file mode 100644 index eac7637..0000000 --- a/app/src/main/res/drawable/ic_alive.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/ic_dead.xml b/app/src/main/res/drawable/ic_dead.xml deleted file mode 100644 index a59b991..0000000 --- a/app/src/main/res/drawable/ic_dead.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/ic_placeholder.xml b/app/src/main/res/drawable/ic_placeholder.xml deleted file mode 100644 index 11e94c0..0000000 --- a/app/src/main/res/drawable/ic_placeholder.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index ed1c066..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,11 +0,0 @@ - - diff --git a/app/src/main/res/layout/fragment_character_details.xml b/app/src/main/res/layout/fragment_character_details.xml deleted file mode 100644 index 1bd6360..0000000 --- a/app/src/main/res/layout/fragment_character_details.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_character_list.xml b/app/src/main/res/layout/fragment_character_list.xml deleted file mode 100644 index d6c4cfa..0000000 --- a/app/src/main/res/layout/fragment_character_list.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_episode_list.xml b/app/src/main/res/layout/fragment_episode_list.xml deleted file mode 100644 index 445490b..0000000 --- a/app/src/main/res/layout/fragment_episode_list.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_character.xml b/app/src/main/res/layout/item_character.xml deleted file mode 100644 index a38d81d..0000000 --- a/app/src/main/res/layout/item_character.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_episode.xml b/app/src/main/res/layout/item_episode.xml deleted file mode 100644 index 30c7493..0000000 --- a/app/src/main/res/layout/item_episode.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index c9ad5f9..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index c9ad5f9..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 2c416f71710be42c9c4869b4376414c17758801d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3278 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 M07*qoM6N<$g2tCZegFUf diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index ec199a514ff2ccbbc84f4ea8296bace00714be0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6418 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 w(O~NklcY% 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 BPHO-F diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 88d6634dbb5f5f75ba284047eb9e8de4e9070eca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3248 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 PAP;%E`njxgN@xNACo%-E diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 08d093090976f708f9d330d857670bbe5ca8ea33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13833 zcmV+kHulMhP)_Wo+r#28bIMmL(olufUje|mP4{B}1ny;zan>(D`pbU})O6afLL3W6ebtf+v3 zVnYSuf8KD$j{?4{HNZ*Y$$w8Uc-b@}V`%c%<>D;qet| zIWAwm+~J|+z;|rrkt)9%*U+~YOoj&>VV*Sp2GjBuk9ZzCq{h$&luLYEkmI5p%5k}! zp&ZKRl=EC_1z5kxYl)ZFHdy1D`)LBK_vl7#BL(n(JW_ZZ)&iJ|YCur{LR~a2tAR^= zrxq=BSYGQJ>JLD#R_c22w3u8;XajgOXn+QX0+_A@i$0(dfRfjyez^_u9`4b6NO~pS zb-;OrM?Q}qH8jly`SiCb(EW{#bmq*No&?k-2_|(@_oKY0S9*cexxi63RsZI(Rzuq; znnq^<&PqxmzkmSx=9_QG0JM{$nbdC!_xPXI=Ark{jpwLygO_-$)B+s6&C~hw=P58G zg#I(ph_dtZ>9^m0>o%}lxNxC8Gp7k8-1EyCT(6fOwF4e?;Ea}PU7g-sxEdjT|NZym z?CwspH*TfLE^bu5dNp0Vc(KdD^Vw&g(SqV)UEhB}gD7DRMr)g+-b0Jl!E2sGU;cSc z4LKJ(Ly%v8{WY1}J5X`c2})R9K@+TP>CmU2b}4uOS~pKmGBPpI+q|ja=$xFBKE2vV z3)fM5{j!XiT$QP6ZJcCHU~KP5C5KK@@xkL1I)5R#uyDWp^2;s(&(A;qOtaI{=tBmo zt;)5d9-O*q+o@sJuKTltr@z|ka5c59lSifRXgqL$EIhmgfCPwG6FEiCq=@KfA?(il zF7T})Hd_-_?v%K86PdfHuF7-6!=yGp;o9c#PZtoBukYotSwrh|iAJcYttI=Qux0>Z zvLadxHj%59Xnbr%^sICaLk)wL1k>|Sl5jz4?~LV3*- zJ%NA!PEG4{Y2a_o+O?#Lp3wq880l5pX{?nkZQH)RQ%Lov%&R7{*_yFpoj8AH%`TeE z0O};depyW$eaE1msBLcl416cLJG74aC|$CI+!Io+08j}?^_mJYcXSqJ?rOf{=&@sD z>F7k!Wh({G!ufM|?x)GlD*Eob?>h5-nzhk|3m0N|O8fkwd6AlzHGpq?v6^dssk>q^ z+4%)DB_rob07*XNo0dhM{sA2p^x3m#X-ZHqc_yaOf&<5z&s|V|kc?g2=)eE{Z>I+$ zmGsE3zy4arn(z8Qq^qwGy>sWz4UuIP-D0vdN7Rg&G_7QbRsdlX?mJ9QQE`-zm`FeU z^pjraW&zSPCgb>g;r_!d&Z__jVT7*8wJ9cziF<8RQ`68t6uDNOhF^a91%bf>5PO{Q7iHf(OG=u`6Z!qw zb$eSqr-{24H61$C)%U1?==5iwefH!v4I)K_^36QTum39vPmh5ICTXIb1I^u5-!6bK zA{QY3O@AT zGiS($ITb)wbl_;a=dukBr`m1Xy7QjT!#iWgiMIBF1Oq&Cb8^XgYN%F^ ztF__6U_&Ha-+UU(r@kQtO%P%3zWVB`r7WAi8nQAt(}hxuNVPamr#(&I@I*#MM^jWx zj1UA|;_uF#(+NW|t3 zI-493%`Pn~qmYOQnrvc1d)WM5r6#(7P{Zldr)NM$24~6?md_LLaq~*NP7V?R1PIhk zaPuOE$XJ@_;zpJ(uH+XSLTPj6(B`TtI?kk)iTf3x`i-CDsZ54bHdJ*8KuYmt68u@z;io~csL|hqx*#(r5nMtQU z|D1O0+)49_iUeRRRIX(1J%xN{XHx9aa&b?%H+X^eq0^{zaam`kJzx^Qt*WYe&>%>) z2JhM2)rnE?0V^kGnzLnxRw2PfN4aWn!2+_M7EKl`7-%VXUtfA>`~)GKs{zo}jG(+C z`u98UlBtsmS@};T*Z5?LUABhiZm$=~T+R0PQ{YZUS1%(M7)Y&!LkP(~_Hf6Dr5B2L&(#&4T3th!~S_=q{w`)6XaIFv2 zCz-RR{o;!+x+M7uS;4f|)z!TY8E)LTv0qP_uD+}mYrC_i2T!DbNT{f1{v(1%l-VMq z&m2kDWNt@I*{M^fcCrlnce^Q5Oc!5-dv};F%>j4VW@<>62u~sBv(|2+>18V^s&skt zn7L{_bF3QS!XrxE6#xQC<;JlE0Ov>r!_D zh)Ez>G8yeGGnT*m07WlZMV1W8kF9L!6BARib8;jfUmpsX>i_!)^e2_O8=2YK&_`zG zG{M=GoMPfBiOFuKaVrKeLIvqrS>3Y48eZ9#Uw(OZ`SRs|lOXEbUEHTHo06>VG+mlz zEHgWs+!Irq%SJn*ZNN1EnsH`kk z);8qAf(KzQ>41x`jI3>Y$js4M#Iw37)o}rl^@9fw&WB99+^tuL^SN{9o>w|}^;8E8 zEC?KD??`#O8at5R+DBgO$xXDhqB*k@skUM*9jV{ZE^su*$;Lg@w5ygjuU<}Z(UCOH z%9?_53w6%;YX&Oa5>hBFBeOe~Tnj?Y=JFB~>8>Z#QpG|0l=YPMQLpcD^6(UEuJjR9 zc3lIFwRa-FDc-bo!)gHneSy;&m^Lh5Ob$*CWbPj%xRgHEHJ7yy>Xo`n`)H;)nwpx* z5gY0MLUH^In%}AvNu@T$-+nJzb)KYC(7` zxC-*i^#TFFwr^V%)l{sZP36mIJ#!okaGfpd%V}q2g&@(b@uhy*xzWqo~p=XzvH+=ofl$exP(v{gH^bop|6STVvy*A`>5fie6IQ>Jx4k8bN7^@oj>qp|*;$ zQ_xy(qUaSkqIYHLe=KAyC?tV943 zTFhDHLJ`GfTF;TTxt7cWL&(V9k*0=*(x%OuMNgrgcp&+>h}E?Txgg14WG7|0iR@UPTM!FzXCKTSWE2Kyn$k; zPoqh!VH_f+)2uZW!p%pTLf@JnfC=%R3N5Sau?C;qTDRXOi3gwzrZ$EfWVE9 zUc5qd3bAl;74e|D9Xse-7HD^xG0gM9g9rDr%x{p<={{G@eZKzs>sOU-sNGGT@nqnM zELpUOEF7K4Dj-j`o)m z9TC^#$-K>&9~66)D=k^NROH6Gfn*CZjfPt*SFRib*p-cSYOhFdz}@#r&n6Q#V-wjN znOT^Tvx6-K`FT@9Or-eibOz-VFE_HYu_9wjOPa*y$J94~LgtrTQ7esePRYonM_zbQ z08ig^3ySA#!lUS8Hm#n1{bT22z&&jRvkd_s@|V$ES_?uU>;^`T1gq1`}mQu zwKau>2GO#GMZ(i+tlJ{IH{`z*Zwnd>{N~WEZNk&qyk-S0VvXkSKZT6=^VWgEB72{` zeXjrk){UVnh{=?|4rTG7;ZiE9>0NUxijIw?b6v}kEp?Ee+bxfw!HB4vZ#c;kIl@&BAE}G0NE$HJ(ljxssjbRhH zQ?L6#sfalf>$rr3uGTy)$TWE8)~#DpfC0S$q~?7MIDh_pb$0*=C6-my)f7B!8W}sQ z$cr^YTIDv;v!^4OZLEV|vt&`LZhQ5*RaC!qvoJ?p8IeB0V1n7KV^0vJA4%&g^;iXR zfE=UZC^9C7zV7_yRBZwX6^r}!?WgL*Z z&0FI7&1B{1*s4h?Vy-idg?R$P$9vit`)Vu6!^M#{tzO=IPLT5eA5SVTE&ly)It*|l zQ%_&v`nQ+6vknRqW~;T%Al(pDyoAs}d3m`Vu)qKspfCUF&vr0g_;q~rWaJrcD}riC zscFJ9bC?!QNeCjsylElX=#e=qVn+>`n;6mR#l<=a9RomHRFF+>&JMyW!+F53 zeB4!Zc=vXl&(pNChFnxG6fifxjqt-E;Xnk3hj&F!MZL@z-1#kAwqybeI`bgdy7A-3 zLtS0ZF7*aO0Fe4X{;PEHVp4f}(F7+I3!~tQ0G-$DOiGv;tJM^xCd5%x=u|oe6Q-l! z6%e_*IM6}{(x(g>8w)eqT)s@Nb6`}gD5J6F7FvUk2qI!VSV+XQo-kWilz6}jFpb#) z9t2G2#Df(6Gh@b#p^Tf8lK)&X6aXnMKipX?5w>!0pqJl$Uqpo!L7@A5!Q44l00^AO z+QO9fAhD{a;4v2F&n16v4_Y)Ym!|r9(NPqo>3I$mvbn09DQ4;Fmc1EwHIjYAbc&ui zv&&ax=#yMMbm-7&V`Jk{GDF{2SMzmUeSJN)yFT9&=?h&38V(>Yh7D7YUQiD-+A;ZD z$U@cx5NeklY%Dtj9*o`96=Z8=PJs-b5(ZO8&oh_JpL1M7Gnbpc?^Cjz8cMzafrhe= z8LW;V(x*cH>qM}S%=TDZs{T#=jtgq96&VL+m9lmqPjFi z(Lo}88QQS4wA31y(1}P(01Y^E=8T`@KL%sI&f+&tE#HbOKgQKYR(F73UIPUIlZEq0AuIt?FY?=`tFZLHx?~ZYrf#K}r zNYg^5(vl@h+B^^1;e|y+h?OHq3#gx`vZ{(K*xOR)ZAku(Wj?oS*RF2aMNwBz3{{f+ zu%OufMv0BKkJn#+9dEjkN$NHb=$v&KZaq6Pfuvd@v>kOKkLMOZ&i0>-WF|58TW*dZ4EO1T~+XlS3bxTT(brv_6Sd z5K~iYYudAQlh!y8mLp>q!C&>PKZf9gf`ddM8kX%iJKBrZ!FsQ#Wz96v+D2<7B|zjX zH^A$v&K&vz2pHJ6Z{Oh&BSxTAa6gHWR{76$@=YVy7Jt@LF(6dnz46u<@=2SkS0_}( zB{sLQX|*f^3;(RGEJb8npSaVeO`FKW)rI!UNOXQiDg^}v>E$^=s|AIJYu|E8tB{urC2cZ6`sj2rd`p)zefM6QXc+#2Gxv__jXse=Y zL0M}6g7!fg14+%IoDA~v@)8w~?ePtv!dcT;G3YjyFKf<)0f+&Bx~I z!b}zy7Yo-vE-IXMRaKA+n?YRwgra;-ck=c2B!4zdQT(38 zh579^VOTUThy1)esA}y>ijR&IfOByxw?{SW)dwpc&vF{R&f3T(S75S zk3VdcM56#KXo?T19PPw1<*O}Y1rY76EyXft6ydKbEp9Gk!?{uZv9x#|d9mh09?ja^ zl>W(P4}rsEjmGDQabe}gcpE!POHUV#!3`lF#v16nP5_eX>H569yeAnvKN~85jvPHo z7S1ZM7*BD31G4hS+QEUA6cxyf`=(Zfj`i&DqU>!fDKaFGmY2+@P36mJ^P1%%1+urc zvenNbKnVh^Ub5=z;mW{SAj)K+;gGOJ?GT2etrhvWyHb8;syHular3j%Xijp1SdEGj zSAZYegJW@{yPv<{ec)e)l2AQy;>0ih{{Apw*W20I^=}tI>FMc@@(I2-#8M87xj8wc ziivO08t#K}2@tiWnG)Dc<;|Jh z;{UT^qbO_ktY)o)T5Dwfu~vR>O=a_YkMG+}Ud(|uu3YkaRz5XJY}w#HH=o8?*@*k< zj#U@>#DSz2_5*vZ&*=;xCY68V5C7K?0R(SnoV6{bZr=94wzv$YOn#z8jWQEkn5Ql4 zSLs~ujAjTR)fg~wZJ9L`gh8{YclyXlPoc!P={j}$aCNe$YUWF#LJ`%GrpBc5@Swv? zx(z80rtZeGL-382mDN-20!XPuWcT(ic5Mx=m<;ZAN@}X8jaG7E@W#gTQ@j-`P-W$y zuZK#sVCjlg79ia)eK1$b-wLzm(9G!(IyL8Xva_M>8`p|!J;}h0ofb+fR;(~I;Isfx zV`Jm#F=NI&1Z>E3M%w`5aXZ`K#-7ZDX&c8+oDce1=K#v?Sr)kE~}Q3|#~1AJ-8 zf`Tpq5VTVs^QZ8se$6X25SY{jKv>BNBHaLjF98%8GL_b?UvH2AQc@Z9_4S7t6MqFZ zBt}|2`i>qw8eJKN{PfdLHHHKrXrI}0=7^P^noE4Jk%>Q(*H3qE6M{j_^Mc&WE?esb z5)Lhdq$+*~mr0Cm--OjxtRZ(ce@Y=fR>|712iHYg8gz;Vf?2JrtJ}?(7$&jNW?5?= zR#AAy(fe>e=%p&7S6DTy$j}Afmwey*@ zSu;q**Oxpan#LI$(|;yR5)IQ0sQyQ@B2g^uS+!~v+TPtNvC-zrj6NP79$3nHOH)%* zfT5JMB8zQlV@nfk?a3u7j>6|Jq_|~kL=je=*gom^L@So}OfOwQR)HZj-e^*nH`D|v zM(aFXzylZF$HR>#F<QmNpD4bI5Oc$rW1i=jrNaf7hWNVM+Q zu|v4`FTe4|@7q8%ogjy>NcN60JFVl!)eeApf{oo3iy+g_Ea1VeP;_w3no>d7acL=0%qv(G-;zdZoq zxNi9H;e+_+aK5Q^5V8S^xcA3y#k{yFs6v118_wl-dyDMPWl5xQQe^@_%tD|DwvDMf3VV$a{qR~<>ujM<5lnmCiv`8E1MW8`JbrUkiKv}Vad(TKdEwo;^0=Fgo& zmZrwEebc(;?*c%LEG;Rkb`KfZIf$AeG)ONhDG?nwT-@A51*V~SV9<(-7cb5R79=Kg z+5(~P`|rOGv<<1Ks4z1mBCTy;g@vuNOLNb|7R@c^WK(2#i12{41p|?nD#%P1LPz@+ zWbu(lLq;7b22T3Nb)<|M`QIXs%Zvw3sV$vPnT_sw*@e8pB(nyWVqA^WaLppkb>N=kAC79=Kg z0#Ki~-+miJ`W8=5&u5t2ePgIud5ppZ3&=7sq}2{z6U@xSwoaM=g4RGZ8FfR@G$?h| zOr#=3G0xhI%vAPdGI=7|`FT>s(Y>^`X&05$Y@iMN+BJMC73a?tIWlZmH#Nc+z=X7*&7R|`9y2Ng3s9pvAJ(&aBzkmOCCMG8T02X8rQKv3teL$9m3>k7WzaGhI zY_p*fX`}$momHZy2IdR>oWX;f3J^uo8ltFuK*C1{n)XPVXm;@97;G) z-qE61jLjNyYTz|B6|2d_$(GhM?WE}3G#c~Kd*s8KX|jchXk?Bp5^~a$sVFy-;-jaD z0y2PV&C-Qr%0D}in%(yzSo%3%IEqOq|t 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 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index f72aa912753dda95f8a9228c95d181782ba934f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27424 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 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 0d31c90361ef9296424ef3197ca4ce435f019fe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20677 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 gN`zc5@ESb+4 - - - - - - - - - - - - - diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml deleted file mode 100644 index 10e5b96..0000000 --- a/app/src/main/res/values-w600dp/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 24dp - - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml deleted file mode 100644 index 9f42545..0000000 --- a/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - #008577 - #00574B - #D81B60 - - #E6555555 - - @color/transparentGray - @color/transparentGray - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index ac7f5df..0000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 16dp - diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml deleted file mode 100644 index f42ada6..0000000 --- a/app/src/main/res/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - #FFFFFF - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index 5832c69..0000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,18 +0,0 @@ - - Rick and Morty - - No network connections - Something went wrong! - - STATUS - SPECIES - GENDER - ORIGIN - LAST LOCATION - - id: %1$d - created: %2$s - - No offline data!\nConnect network connection and try again… - - (Killed) - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index f4b555d..0000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/release/res/xml/network_security_config.xml b/app/src/release/res/xml/network_security_config.xml deleted file mode 100644 index 82cc113..0000000 --- a/app/src/release/res/xml/network_security_config.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharacterDetailsTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharacterDetailsTest.kt deleted file mode 100644 index 78fe2ea..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharacterDetailsTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.test.ApiFactory -import com.mohsenoid.rickandmorty.test.CharacterDataFactory -import com.mohsenoid.rickandmorty.test.DataFactory -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.just -import io.mockk.runs -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Test - -@OptIn(ExperimentalCoroutinesApi::class) -class RepositoryGetCharacterDetailsTest : RepositoryTest() { - - @Test - fun `test if getCharacterDetails calls networkClient when isOnline`() = runBlockingTest { - // GIVEN - val characterId: Int = DataFactory.randomInt() - stubStatusProviderIsOnline(isOnline = true) - stubApiFetchCharacterDetails(ApiFactory.CharacterDetails.makeCharacter()) - stubSbQueryCharacter( - character = CharacterDataFactory.makeDbCharacter(characterId = characterId), - ) - stubDbInsertOrUpdateCharacter() - - // WHEN - repository.getCharacterDetails(characterId = characterId) - - // THEN - coVerify(exactly = 1) { api.fetchCharacterDetails(characterId = any()) } - - coVerify(exactly = 1) { db.insertOrUpdateCharacter(character = any()) } - coVerify(exactly = 1) { db.queryCharacter(characterId = any()) } - } - - @Test - fun `test if getCharacterDetails calls db only when isOffline`() = runBlockingTest { - // GIVEN - val characterId: Int = DataFactory.randomInt() - stubStatusProviderIsOnline(isOnline = false) - stubSbQueryCharacter(CharacterDataFactory.makeDbCharacter(characterId = characterId)) - - // WHEN - repository.getCharacterDetails(characterId = characterId) - - // THEN - coVerify(exactly = 0) { api.fetchCharacterDetails(characterId = any()) } - coVerify(exactly = 1) { db.queryCharacter(characterId = any()) } - } - - private suspend fun stubApiFetchCharacterDetails(character: ApiCharacter) { - coEvery { api.fetchCharacterDetails(characterId = any()) } returns - ApiResult.Success(character) - } - - private fun stubDbInsertOrUpdateCharacter() { - coEvery { db.insertOrUpdateCharacter(any()) } just runs - } - - private fun stubSbQueryCharacter(character: DbCharacter?) { - coEvery { db.queryCharacter(characterId = any()) } returns character - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharactersTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharactersTest.kt deleted file mode 100644 index 3dfce72..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetCharactersTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.test.ApiFactory -import com.mohsenoid.rickandmorty.test.CharacterDataFactory -import com.mohsenoid.rickandmorty.test.DataFactory -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.just -import io.mockk.runs -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Test - -@OptIn(ExperimentalCoroutinesApi::class) -class RepositoryGetCharactersTest : RepositoryTest() { - - @Test - fun `test if getCharactersByIds calls networkClient when isOnline`() = runBlockingTest { - // GIVEN - val characterIds: List = DataFactory.randomIntList(count = 5) - stubStatusProviderIsOnline(isOnline = true) - stubApiFetchCharactersByIds(ApiFactory.Characters.makeCharacters()) - stubDbQueryCharactersByIds(CharacterDataFactory.makeDbCharacters(count = 5)) - stubDbInsertOrUpdateCharacter() - - // WHEN - repository.getCharactersByIds(characterIds = characterIds) - - // THEN - coVerify(exactly = 1) { api.fetchCharactersByIds(characterIds = any()) } - - coVerify(exactly = 1) { db.insertOrUpdateCharacter(character = any()) } - coVerify(exactly = 1) { db.queryCharactersByIds(characterIds = any()) } - } - - @Test - fun `test if getCharactersByIds calls db only when isOffline`() = runBlockingTest { - // GIVEN - val characterIds: List = DataFactory.randomIntList(count = 5) - stubStatusProviderIsOnline(isOnline = false) - stubDbQueryCharactersByIds(CharacterDataFactory.makeDbCharacters(count = 5)) - - // WHEN - repository.getCharactersByIds(characterIds = characterIds) - - // THEN - coVerify(exactly = 0) { api.fetchCharactersByIds(characterIds = any()) } - coVerify(exactly = 1) { db.queryCharactersByIds(characterIds = any()) } - } - - private fun stubApiFetchCharactersByIds(characters: List) { - coEvery { api.fetchCharactersByIds(characterIds = any()) } returns - ApiResult.Success(characters) - } - - private fun stubDbQueryCharactersByIds(characters: List) { - coEvery { db.queryCharactersByIds(characterIds = any()) } returns characters - } - - private fun stubDbInsertOrUpdateCharacter() { - coEvery { db.insertOrUpdateCharacter(any()) } just runs - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetEpisodesTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetEpisodesTest.kt deleted file mode 100644 index 971ccde..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryGetEpisodesTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisodes -import com.mohsenoid.rickandmorty.data.api.model.ApiResult -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.test.ApiFactory -import com.mohsenoid.rickandmorty.test.EpisodeDataFactory -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.just -import io.mockk.runs -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Test - -@OptIn(ExperimentalCoroutinesApi::class) -class RepositoryGetEpisodesTest : RepositoryTest() { - - @Test - fun `getEpisodes calls networkClient and db when isOnline`() = runBlockingTest { - // GIVEN - stubStatusProviderIsOnline(isOnline = true) - stubApiFetchEpisodes(ApiFactory.Episode.makeApiEpisodes()) - val entityEpisodes = EpisodeDataFactory.makeDbEpisodes(count = 5) - stubEpisodeDaoQueryAllEpisodesByPage(entityEpisodes) - stubDbInsertEpisode() - - // WHEN - repository.getEpisodes(page = 1) - - // THEN - coVerify(exactly = 1) { api.fetchEpisodes(page = 1) } - coVerify(exactly = 1) { db.insertEpisode(entityEpisode = any()) } - coVerify(exactly = 1) { db.queryAllEpisodesByPage(page = any(), pageSize = any()) } - } - - @Test - fun `if getEpisodes calls db only when isOffline`() = runBlockingTest { - // GIVEN - stubStatusProviderIsOnline(isOnline = false) - stubEpisodeDaoQueryAllEpisodesByPage(EpisodeDataFactory.makeDbEpisodes(count = 5)) - - // WHEN - repository.getEpisodes(page = 1) - - // THEN - coVerify(exactly = 0) { api.fetchEpisodes(page = 1) } - coVerify(exactly = 1) { db.queryAllEpisodesByPage(page = any(), pageSize = any()) } - } - - private fun stubApiFetchEpisodes(episodes: ApiEpisodes) { - coEvery { api.fetchEpisodes(page = any()) } returns ApiResult.Success(episodes) - } - - private fun stubDbInsertEpisode() { - coEvery { db.insertEpisode(any()) } just runs - } - - private fun stubEpisodeDaoQueryAllEpisodesByPage(entityEpisodes: List) { - coEvery { db.queryAllEpisodesByPage(page = any(), pageSize = any()) } returns entityEpisodes - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryTest.kt deleted file mode 100644 index 90960a7..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/RepositoryTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.mohsenoid.rickandmorty.data - -import com.mohsenoid.rickandmorty.data.api.ApiRickAndMorty -import com.mohsenoid.rickandmorty.data.db.DbRickAndMorty -import com.mohsenoid.rickandmorty.domain.Repository -import com.mohsenoid.rickandmorty.util.StatusProvider -import io.mockk.MockKAnnotations -import io.mockk.every -import io.mockk.impl.annotations.MockK -import org.junit.Before - -open class RepositoryTest { - - @MockK - internal lateinit var db: DbRickAndMorty - - @MockK - internal lateinit var api: ApiRickAndMorty - - @MockK - internal lateinit var statusProvider: StatusProvider - - lateinit var repository: Repository - - @Before - fun setUp() { - MockKAnnotations.init(this) - - repository = RepositoryImpl( - db = db, - api = api, - statusProvider = statusProvider, - ) - } - - fun stubStatusProviderIsOnline(isOnline: Boolean) { - every { statusProvider.isOnline() } returns isOnline - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMortyTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMortyTest.kt deleted file mode 100644 index 2afbe60..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/db/DbRickAndMortyTest.kt +++ /dev/null @@ -1,253 +0,0 @@ -package com.mohsenoid.rickandmorty.data.db - -import android.app.Application -import android.os.Build -import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.room.Room -import androidx.test.core.app.ApplicationProvider -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.test.CharacterDataFactory -import com.mohsenoid.rickandmorty.test.DataFactory -import com.mohsenoid.rickandmorty.test.EpisodeDataFactory -import io.mockk.every -import io.mockk.mockkObject -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.koin.core.context.stopKoin -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import java.io.IOException -import kotlin.test.assertContains -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNotNull -import kotlin.test.assertTrue - -@OptIn(ExperimentalCoroutinesApi::class) -@Config(sdk = [Build.VERSION_CODES.P]) -@RunWith(RobolectricTestRunner::class) -class DbRickAndMortyTest { - - @get:Rule - val instantExecutorRule = InstantTaskExecutorRule() - - private lateinit var roomDb: DbRickAndMorty.Db - - private lateinit var db: DbRickAndMorty - - @Before - fun setUp() { - val application: Application = ApplicationProvider.getApplicationContext() - mockkObject(DbRickAndMorty.Db) { - roomDb = Room.inMemoryDatabaseBuilder(application, DbRickAndMorty.Db::class.java) - .allowMainThreadQueries() - .build() - - every { DbRickAndMorty.Db.create(application) } returns roomDb - - db = DbRickAndMorty(application) - } - } - - @After - @Throws(IOException::class) - fun tearDown() { - roomDb.close() - stopKoin() - } - - @Test - fun `insertEpisode can inserts a new Episode`() = runBlockingTest { - // GIVEN - val expectedEntityEpisode: DbEpisode = EpisodeDataFactory.makeDbEpisode() - - // WHEN - db.insertEpisode(expectedEntityEpisode) - - // THEN - val actualEntityEpisodes: List = db.queryAllEpisodes() - - assertFalse(actualEntityEpisodes.isEmpty()) - assertContains(actualEntityEpisodes, expectedEntityEpisode) - } - - @Test - fun `insertEpisode with same ID updates the old one`() = runBlockingTest { - // GIVEN - val episodeId: Int = DataFactory.randomInt() - val oldEntityEpisode: DbEpisode = - EpisodeDataFactory.makeDbEpisode(episodeId = episodeId) - val updatedEntityEpisode: DbEpisode = - EpisodeDataFactory.makeDbEpisode(episodeId = episodeId) - - // WHEN - db.insertEpisode(oldEntityEpisode) - db.insertEpisode(updatedEntityEpisode) - - // THEN - val actualEntityEpisodes: List = db.queryAllEpisodes() - - assertFalse(actualEntityEpisodes.isEmpty()) - assertContains(actualEntityEpisodes, updatedEntityEpisode) - // assertNotContains(actualEntityEpisodes, oldEntityEpisode) - } - - @Test - fun `insertCharacter can inserts a new Character`() = runBlockingTest { - // GIVEN - val expectedCharacter: DbCharacter = CharacterDataFactory.makeDbCharacter() - - // WHEN - db.insertOrUpdateCharacter(expectedCharacter) - - // THEN - val actualCharacter: DbCharacter? = - db.queryCharacter(expectedCharacter.id) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter, expectedCharacter) - } - - @Test - fun `insertCharacter with same ID updates the old one`() = runBlockingTest { - // GIVEN - val characterId: Int = DataFactory.randomInt() - val oldCharacter: DbCharacter = - CharacterDataFactory.makeDbCharacter(characterId = characterId) - val updatedCharacter: DbCharacter = - CharacterDataFactory.makeDbCharacter(characterId = characterId) - - // WHEN - db.insertOrUpdateCharacter(oldCharacter) - db.insertOrUpdateCharacter(updatedCharacter) - - // THEN - val actualCharacter: DbCharacter? = db.queryCharacter(characterId) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter, updatedCharacter) - } - - @Test - fun `queryCharacter returns the same Character details inserted`() = runBlockingTest { - // GIVEN - val characterId: Int = DataFactory.randomInt() - val expectedCharacter: DbCharacter = - CharacterDataFactory.makeDbCharacter(characterId = characterId) - - // WHEN - db.insertOrUpdateCharacter(expectedCharacter) - - // THEN - val actualCharacter: DbCharacter? = db.queryCharacter(characterId) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter, expectedCharacter) - } - - @Test - fun `queryCharactersByIds returns the Characters asked for`() = runBlockingTest { - // GIVEN - val expected: DbCharacter = CharacterDataFactory.makeDbCharacter() - val notExpected: DbCharacter = CharacterDataFactory.makeDbCharacter() - val expectedCharacterIds: List = listOf(expected.id) - - // WHEN - db.insertOrUpdateCharacter(expected) - db.insertOrUpdateCharacter(notExpected) - - // THEN - val characters: List = - db.queryCharactersByIds(expectedCharacterIds) - - assertFalse(characters.isEmpty()) - assertContains(characters, expected) - // assertNotContains(characters, expected) - } - - @Test - fun `Character which status is Alive and is not KilledByUser isAlive`() = runBlockingTest { - // GIVEN - val expectedCharacterId: Int = DataFactory.randomInt() - val expectedCharacter: DbCharacter = CharacterDataFactory.makeDbCharacter( - characterId = expectedCharacterId, - status = ALIVE, - isAlive = true, - isKilledByUser = false, - ) - - // WHEN - db.insertOrUpdateCharacter(expectedCharacter) - - // THEN - val actualCharacter: DbCharacter? = - db.queryCharacter(expectedCharacterId) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter.status, ALIVE) - assertTrue(actualCharacter.isAlive) - assertFalse(actualCharacter.isKilledByUser) - } - - @Test - fun `test user can kill a Character`() = runBlockingTest { - // GIVEN - val expectedCharacterId: Int = DataFactory.randomInt() - val expectedCharacter: DbCharacter = CharacterDataFactory.makeDbCharacter( - characterId = expectedCharacterId, - status = ALIVE, - isAlive = true, - isKilledByUser = false, - ) - - // WHEN - db.insertOrUpdateCharacter(expectedCharacter) - db.killCharacter(expectedCharacterId) - - // THEN - val actualCharacter: DbCharacter? = - db.queryCharacter(expectedCharacterId) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter.status, ALIVE) - assertTrue(actualCharacter.isAlive) - assertTrue(actualCharacter.isKilledByUser) - } - - @Test - fun `test a Character which isKilledByUser keeps dead after update by insert`() = - runBlockingTest { - // GIVEN - val expectedCharacterId: Int = DataFactory.randomInt() - val expectedCharacter: DbCharacter = CharacterDataFactory.makeDbCharacter( - characterId = expectedCharacterId, - status = ALIVE, - isAlive = true, - isKilledByUser = false, - ) - - // WHEN - db.insertOrUpdateCharacter(expectedCharacter) - db.killCharacter(expectedCharacterId) - db.insertOrUpdateCharacter(expectedCharacter) - - // THEN - val actualCharacter: DbCharacter? = - db.queryCharacter(expectedCharacterId) - - assertNotNull(actualCharacter) - assertEquals(actualCharacter.status, ALIVE) - assertTrue(actualCharacter.isAlive) - assertTrue(actualCharacter.isKilledByUser) - } - - companion object { - private const val ALIVE = "alive" - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapperTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapperTest.kt deleted file mode 100644 index e63df3d..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/CharacterMapperTest.kt +++ /dev/null @@ -1,126 +0,0 @@ -package com.mohsenoid.rickandmorty.data.mapper - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiLocation -import com.mohsenoid.rickandmorty.data.api.model.ApiOrigin -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbLocation -import com.mohsenoid.rickandmorty.data.db.model.DbOrigin -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter -import com.mohsenoid.rickandmorty.domain.model.ModelLocation -import com.mohsenoid.rickandmorty.domain.model.ModelOrigin -import org.junit.Test -import kotlin.test.assertEquals - -class CharacterMapperTest { - - @Test - fun modelToDbCharacter() { - // GIVEN - val apiCharacter = ApiCharacter( - id = CHARACTER_ID, - name = CHARACTER_NAME, - status = CHARACTER_STATUS, - species = CHARACTER_SPECIES, - type = CHARACTER_TYPE, - gender = CHARACTER_GENDER, - origin = ApiOrigin(CHARACTER_ORIGIN_NAME, CHARACTER_ORIGIN_URL), - location = ApiLocation(CHARACTER_LOCATION_NAME, CHARACTER_LOCATION_URL), - image = CHARACTER_IMAGE, - episodes = CHARACTER_EPISODES, - url = CHARACTER_URL, - created = CHARACTER_CREATED, - ) - - val expectedDbCharacter = DbCharacter( - id = CHARACTER_ID, - name = CHARACTER_NAME, - status = CHARACTER_STATUS, - isAlive = CHARACTER_STATUS_ALIVE, - species = CHARACTER_SPECIES, - type = CHARACTER_TYPE, - gender = CHARACTER_GENDER, - origin = DbOrigin(CHARACTER_ORIGIN_NAME, CHARACTER_ORIGIN_URL), - location = DbLocation(CHARACTER_LOCATION_NAME, CHARACTER_LOCATION_URL), - image = CHARACTER_IMAGE, - episodeIds = CHARACTER_EPISODE_IDS, - url = CHARACTER_URL, - created = CHARACTER_CREATED, - isKilledByUser = false, - ) - - // WHEN - val actualDbCharacter: DbCharacter = apiCharacter.toDbCharacter() - - // THEN - assertEquals(expectedDbCharacter, actualDbCharacter) - } - - @Test - fun dbToModelCharacter() { - // GIVEN - val dbCharacter = DbCharacter( - id = CHARACTER_ID, - name = CHARACTER_NAME, - status = CHARACTER_STATUS, - isAlive = CHARACTER_STATUS_ALIVE, - species = CHARACTER_SPECIES, - type = CHARACTER_TYPE, - gender = CHARACTER_GENDER, - origin = DbOrigin(CHARACTER_ORIGIN_NAME, CHARACTER_ORIGIN_URL), - location = DbLocation(CHARACTER_LOCATION_NAME, CHARACTER_LOCATION_URL), - image = CHARACTER_IMAGE, - episodeIds = CHARACTER_EPISODE_IDS, - url = CHARACTER_URL, - created = CHARACTER_CREATED, - isKilledByUser = CHARACTER_IS_KILLED_BY_USER, - ) - - val expectedModelCharacter = ModelCharacter( - id = CHARACTER_ID, - name = CHARACTER_NAME, - status = CHARACTER_STATUS, - isAlive = CHARACTER_STATUS_ALIVE, - species = CHARACTER_SPECIES, - type = CHARACTER_TYPE, - gender = CHARACTER_GENDER, - origin = ModelOrigin(CHARACTER_ORIGIN_NAME, CHARACTER_ORIGIN_URL), - location = ModelLocation(CHARACTER_LOCATION_NAME, CHARACTER_LOCATION_URL), - imageUrl = CHARACTER_IMAGE, - episodeIds = CHARACTER_EPISODE_IDS, - url = CHARACTER_URL, - created = CHARACTER_CREATED, - isKilledByUser = CHARACTER_IS_KILLED_BY_USER, - ) - - // WHEN - val actualModelCharacter: ModelCharacter = dbCharacter.toModelCharacter() - - // THEN - assertEquals(expectedModelCharacter, actualModelCharacter) - } - - companion object { - private const val CHARACTER_ID = 123 - private const val CHARACTER_NAME = "some name" - private const val CHARACTER_STATUS = "dead" - private const val CHARACTER_STATUS_ALIVE = false - private const val CHARACTER_SPECIES = "some species" - private const val CHARACTER_TYPE = "some type" - private const val CHARACTER_GENDER = "some gender" - private const val CHARACTER_ORIGIN_NAME = "some origin name" - private const val CHARACTER_ORIGIN_URL = "some origin url" - private const val CHARACTER_LOCATION_NAME = "some location name" - private const val CHARACTER_LOCATION_URL = "some location url" - private const val CHARACTER_IMAGE = "some image" - private val CHARACTER_EPISODES = listOf( - "https://test.com/api/episode/1", - "https://test.com/api/episode/2", - "https://test.com/api/episode/3", - ) - private val CHARACTER_EPISODE_IDS = listOf(1, 2, 3) - private const val CHARACTER_URL = "some url" - private const val CHARACTER_CREATED = "some created" - private const val CHARACTER_IS_KILLED_BY_USER = true - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapperTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapperTest.kt deleted file mode 100644 index 6581fb1..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/data/mapper/EpisodeMapperTest.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.mohsenoid.rickandmorty.data.mapper - -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisode -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode -import org.junit.Test -import kotlin.test.assertEquals - -class EpisodeMapperTest { - - @Test - fun apiToDbEpisode() { - // GIVEN - val apiEpisode = ApiEpisode( - id = EPISODE_ID, - name = EPISODE_NAME, - airDate = EPISODE_AIR_DATE, - episode = EPISODE_EPISODE, - characters = CHARACTER_CHARACTERS, - url = EPISODE_URL, - created = EPISODE_CREATED, - ) - - val expectedDbEpisode = DbEpisode( - id = EPISODE_ID, - name = EPISODE_NAME, - airDate = EPISODE_AIR_DATE, - episode = EPISODE_EPISODE, - characterIds = CHARACTER_CHARACTER_IDS, - url = EPISODE_URL, - created = EPISODE_CREATED, - ) - - // WHEN - val actualDbEpisode: DbEpisode = apiEpisode.toDbEpisode() - - // THEN - assertEquals(expectedDbEpisode, actualDbEpisode) - } - - @Test - fun dbToModelEpisode() { - // GIVEN - val dbEpisode = DbEpisode( - id = EPISODE_ID, - name = EPISODE_NAME, - airDate = EPISODE_AIR_DATE, - episode = EPISODE_EPISODE, - characterIds = CHARACTER_CHARACTER_IDS, - url = EPISODE_URL, - created = EPISODE_CREATED, - ) - - val expectedModelEpisode = ModelEpisode( - id = EPISODE_ID, - name = EPISODE_NAME, - airDate = EPISODE_AIR_DATE, - episode = EPISODE_EPISODE, - characterIds = CHARACTER_CHARACTER_IDS, - url = EPISODE_URL, - created = EPISODE_CREATED, - ) - - // WHEN - val actualModelEpisode: ModelEpisode = dbEpisode.toModelEpisode() - - // THEN - assertEquals(expectedModelEpisode, actualModelEpisode) - } - - companion object { - private const val EPISODE_ID = 123 - private const val EPISODE_NAME = "some name" - private const val EPISODE_AIR_DATE = "some air date" - private const val EPISODE_EPISODE = "some episode" - private val CHARACTER_CHARACTERS = listOf( - "https://test.com/api/character/1", - "https://test.com/api/character/2", - "https://test.com/api/character/3", - ) - private val CHARACTER_CHARACTER_IDS = listOf(1, 2, 3) - private const val EPISODE_URL = "some url" - private const val EPISODE_CREATED = "some created" - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/AppModuleTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/AppModuleTest.kt deleted file mode 100644 index 09837d9..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/AppModuleTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.mohsenoid.rickandmorty.injection - -import android.os.Build -import com.mohsenoid.rickandmorty.appModule -import org.junit.Test -import org.junit.runner.RunWith -import org.koin.android.ext.koin.androidContext -import org.koin.core.context.startKoin -import org.koin.test.check.checkModules -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -@Config(sdk = [Build.VERSION_CODES.P]) -@RunWith(RobolectricTestRunner::class) -class AppModuleTest : ModuleTest() { - - @Test - fun `check all definitions from appModule`() { - startKoin { - androidContext(application) - modules(appModule) - }.checkModules() - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/DataModuleTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/DataModuleTest.kt deleted file mode 100644 index 20151be..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/DataModuleTest.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mohsenoid.rickandmorty.injection - -import android.os.Build -import com.mohsenoid.rickandmorty.appModule -import com.mohsenoid.rickandmorty.data.dataModule -import com.mohsenoid.rickandmorty.util.KoinQualifiersNames -import org.junit.Test -import org.junit.runner.RunWith -import org.koin.android.ext.koin.androidContext -import org.koin.core.context.startKoin -import org.koin.test.check.checkModules -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -@Config(sdk = [Build.VERSION_CODES.P]) -@RunWith(RobolectricTestRunner::class) -class DataModuleTest : ModuleTest() { - - @Test - fun `check all definitions from dataModule`() { - startKoin { - val appProperties: Map = mapOf( - KoinQualifiersNames.BASE_URL to BASE_URL, - ) - properties(appProperties) - - androidContext(application) - modules(appModule + dataModule) - }.checkModules() - } - - companion object { - private const val BASE_URL = "https://test.com/api/" - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/ModuleTest.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/ModuleTest.kt deleted file mode 100644 index e97468b..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/injection/ModuleTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.mohsenoid.rickandmorty.injection - -import android.app.Application -import android.os.Build -import androidx.test.core.app.ApplicationProvider -import org.junit.After -import org.junit.Before -import org.junit.runner.RunWith -import org.koin.core.component.KoinComponent -import org.koin.core.context.stopKoin -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -@Config(sdk = [Build.VERSION_CODES.P]) -@RunWith(RobolectricTestRunner::class) -abstract class ModuleTest : KoinComponent { - - internal lateinit var application: Application - - @Before - fun setUp() { - application = ApplicationProvider.getApplicationContext() - stopKoin() - } - - @After - fun tearDown() { - stopKoin() - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/ApiFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/ApiFactory.kt deleted file mode 100644 index ff94490..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/ApiFactory.kt +++ /dev/null @@ -1,149 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisode -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisodes -import com.mohsenoid.rickandmorty.data.api.model.ApiInfo -import com.mohsenoid.rickandmorty.data.api.model.ApiLocation -import com.mohsenoid.rickandmorty.data.api.model.ApiOrigin - -object ApiFactory { - - object Episode { - private const val VALUE_COUNT: Int = 1 - private const val VALUE_PAGE: Int = 1 - private const val VALUE_NEXT: String = "" - private const val VALUE_PREV: String = "" - - private const val VALUE_ID: Int = 1 - private const val VALUE_NAME: String = "Pilot" - private const val VALUE_AIR_DATE: String = "December 2, 2013" - private const val VALUE_EPISODE: String = "S01E01" - private const val VALUE_CHARACTER: String = "https://rickandmortyapi.com/api/character/1" - private const val VALUE_URL: String = "https://rickandmortyapi.com/api/episode/1" - private const val VALUE_CREATED: String = "2017-11-10T12:56:33.798Z" - - const val EPISODES_JSON: String = """{ - "info": { - "count": $VALUE_COUNT, - "pages": $VALUE_PAGE, - "next": $VALUE_NEXT, - "prev": $VALUE_PREV - }, - "results": [ - { - "id": $VALUE_ID, - "name": $VALUE_NAME, - "air_date": $VALUE_AIR_DATE, - "episode": $VALUE_EPISODE, - "characters": [ - $VALUE_CHARACTER - ], - "url": $VALUE_URL, - "created": $VALUE_CREATED - } - ] -}""" - - internal fun makeApiEpisodes(): ApiEpisodes { - val info = ApiInfo( - count = VALUE_COUNT, - pages = VALUE_PAGE, - next = VALUE_NEXT, - prev = VALUE_PREV, - ) - - val episode = ApiEpisode( - id = VALUE_ID, - name = VALUE_NAME, - airDate = VALUE_AIR_DATE, - episode = VALUE_EPISODE, - characters = arrayListOf(VALUE_CHARACTER), - url = VALUE_URL, - created = VALUE_CREATED, - ) - - return ApiEpisodes( - info = info, - results = arrayListOf(episode), - ) - } - } - - object Characters { - const val CHARACTERS_JSON: String = "[\n ${CharacterDetails.CHARACTER_DETAILS_JSON}\n]" - - internal fun makeCharacters(): List { - val character: ApiCharacter = CharacterDetails.makeCharacter() - return arrayListOf(character) - } - } - - object CharacterDetails { - private const val VALUE_ID: Int = 1 - private const val VALUE_NAME: String = "Rick Sanchez" - private const val VALUE_STATUS: String = "Alive" - private const val VALUE_SPECIES: String = "Human" - private const val VALUE_TYPE: String = "" - private const val VALUE_GENDER: String = "Male" - private const val VALUE_ORIGIN_NAME: String = "Earth (C-137)" - private const val VALUE_ORIGIN_URL: String = "https://rickandmortyapi.com/api/location/1" - private const val VALUE_LOCATION_NAME: String = "Earth (Replacement Dimension)" - private const val VALUE_LOCATION_URL: String = "https://rickandmortyapi.com/api/location/20" - private const val VALUE_IMAGE: String = - "https://rickandmortyapi.com/api/character/avatar/1.jpeg" - private const val VALUE_EPISODE: String = "https://rickandmortyapi.com/api/episode/1" - private const val VALUE_URL: String = "https://rickandmortyapi.com/api/character/1" - private const val VALUE_CREATED: String = "2017-11-04T18:48:46.250Z" - - const val CHARACTER_DETAILS_JSON: String = """{ - "id": $VALUE_ID, - "name": "$VALUE_NAME", - "status": "$VALUE_STATUS", - "species": "$VALUE_SPECIES", - "type": "$VALUE_TYPE", - "gender": "$VALUE_GENDER", - "origin": { - "name": "$VALUE_ORIGIN_NAME", - "url": "$VALUE_ORIGIN_URL" - }, - "location": { - "name": "$VALUE_LOCATION_NAME", - "url": "$VALUE_LOCATION_URL" - }, - "image": "$VALUE_IMAGE", - "episode": [ - "$VALUE_EPISODE" - ], - "url": "$VALUE_URL", - "created": "$VALUE_CREATED" -}""" - - internal fun makeCharacter(): ApiCharacter { - val origin = ApiOrigin( - name = VALUE_ORIGIN_NAME, - url = VALUE_ORIGIN_URL, - ) - - val location = ApiLocation( - name = VALUE_LOCATION_NAME, - url = VALUE_LOCATION_URL, - ) - - return ApiCharacter( - id = VALUE_ID, - name = VALUE_NAME, - status = VALUE_STATUS, - species = VALUE_SPECIES, - type = VALUE_TYPE, - gender = VALUE_GENDER, - origin = origin, - location = location, - image = VALUE_IMAGE, - episodes = arrayListOf(VALUE_EPISODE), - url = VALUE_URL, - created = VALUE_CREATED, - ) - } - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/CharacterDataFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/CharacterDataFactory.kt deleted file mode 100644 index 22bdd5d..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/CharacterDataFactory.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import com.mohsenoid.rickandmorty.data.api.model.ApiCharacter -import com.mohsenoid.rickandmorty.data.db.model.DbCharacter -import com.mohsenoid.rickandmorty.domain.model.ModelCharacter - -object CharacterDataFactory { - - internal fun makeDbCharacter( - characterId: Int = DataFactory.randomInt(), - status: String = DataFactory.randomString(), - isAlive: Boolean = DataFactory.randomBoolean(), - isKilledByUser: Boolean = false, - ): DbCharacter = - DbCharacter( - id = characterId, - name = DataFactory.randomString(), - status = status, - isAlive = isAlive, - species = DataFactory.randomString(), - type = DataFactory.randomString(), - gender = DataFactory.randomString(), - origin = OriginDataFactory.makeDbOrigin(), - location = LocationDataFactory.makeDbLocation(), - image = DataFactory.randomString(), - episodeIds = DataFactory.randomIntList(count = 5), - url = DataFactory.randomString(), - created = DataFactory.randomString(), - isKilledByUser = isKilledByUser, - ) - - internal fun makeDbCharacters(count: Int): List { - val characters: MutableList = ArrayList() - repeat(count) { - val character: DbCharacter = makeDbCharacter() - characters.add(character) - } - return characters - } - - internal fun makeApiCharacter(characterId: Int = DataFactory.randomInt()): ApiCharacter = - ApiCharacter( - id = characterId, - name = DataFactory.randomString(), - status = DataFactory.randomString(), - species = DataFactory.randomString(), - type = DataFactory.randomString(), - gender = DataFactory.randomString(), - origin = OriginDataFactory.makeApiOrigin(), - location = LocationDataFactory.makeApiLocation(), - image = DataFactory.randomString(), - episodes = DataFactory.randomIntList(count = 5) - .map { "${DataFactory.randomString()}/$it" }, - url = DataFactory.randomString(), - created = DataFactory.randomString(), - ) - - internal fun makeApiCharacters(count: Int): List { - val characters: MutableList = ArrayList() - repeat(count) { - val character: ApiCharacter = makeApiCharacter() - characters.add(character) - } - return characters - } - - internal fun makeCharacter( - id: Int = DataFactory.randomInt(), - status: String = DataFactory.randomString(), - isAlive: Boolean = DataFactory.randomBoolean(), - isKilledByUser: Boolean = false, - ): ModelCharacter = ModelCharacter( - id = id, - name = DataFactory.randomString(), - status = status, - isAlive = isAlive, - species = DataFactory.randomString(), - type = DataFactory.randomString(), - gender = DataFactory.randomString(), - origin = OriginDataFactory.makeOrigin(), - location = LocationDataFactory.makeLocation(), - imageUrl = DataFactory.randomString(), - episodeIds = DataFactory.randomIntList(count = 5), - url = DataFactory.randomString(), - created = DataFactory.randomString(), - isKilledByUser = isKilledByUser, - ) - - internal fun makeCharacters(count: Int): List { - val characters: MutableList = ArrayList() - repeat(count) { - val character: ModelCharacter = makeCharacter() - characters.add(character) - } - return characters - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/DataFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/DataFactory.kt deleted file mode 100644 index 308e096..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/DataFactory.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import java.util.ArrayList -import java.util.UUID -import java.util.concurrent.ThreadLocalRandom - -object DataFactory { - - fun randomString(): String = UUID.randomUUID().toString() - - fun randomStringList(count: Int): List { - val list: MutableList = ArrayList() - - repeat(count) { - list.add(randomString()) - } - - return list - } - - fun randomInt(min: Int = Int.MIN_VALUE, max: Int = Int.MAX_VALUE): Int = - ThreadLocalRandom.current().nextInt(min, max) - - fun randomIntList(count: Int, min: Int = Int.MIN_VALUE, max: Int = Int.MAX_VALUE): List { - val list: MutableList = ArrayList() - - repeat(count) { - list.add(randomInt(min, max)) - } - - return list - } - - fun randomBoolean(): Boolean = Math.random() < 0.5 -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/EpisodeDataFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/EpisodeDataFactory.kt deleted file mode 100644 index ecb6be9..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/EpisodeDataFactory.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import com.mohsenoid.rickandmorty.data.api.model.ApiEpisode -import com.mohsenoid.rickandmorty.data.db.model.DbEpisode -import com.mohsenoid.rickandmorty.domain.model.ModelEpisode - -object EpisodeDataFactory { - - internal fun makeDbEpisode(episodeId: Int = DataFactory.randomInt()): DbEpisode = - DbEpisode( - id = episodeId, - name = DataFactory.randomString(), - airDate = DataFactory.randomString(), - episode = DataFactory.randomString(), - characterIds = DataFactory.randomIntList(count = 5), - url = DataFactory.randomString(), - created = DataFactory.randomString(), - ) - - internal fun makeDbEpisodes(count: Int): List { - val entityEpisodes: MutableList = ArrayList() - repeat(count) { - val entityEpisode: DbEpisode = makeDbEpisode() - entityEpisodes.add(entityEpisode) - } - return entityEpisodes - } - - internal fun makeApiEpisode(episodeId: Int = DataFactory.randomInt()): ApiEpisode = - ApiEpisode( - id = episodeId, - name = DataFactory.randomString(), - airDate = DataFactory.randomString(), - episode = DataFactory.randomString(), - characters = DataFactory.randomIntList(count = 5) - .map { "${DataFactory.randomString()}/$it" }, - url = DataFactory.randomString(), - created = DataFactory.randomString(), - ) - - internal fun makeApiEpisodes(count: Int): List { - val episodes: MutableList = ArrayList() - repeat(count) { - val episode: ApiEpisode = makeApiEpisode() - episodes.add(episode) - } - return episodes - } - - internal fun makeEpisode(episodeId: Int = DataFactory.randomInt()): ModelEpisode = - ModelEpisode( - id = episodeId, - name = DataFactory.randomString(), - airDate = DataFactory.randomString(), - episode = DataFactory.randomString(), - characterIds = DataFactory.randomIntList(count = 5), - url = DataFactory.randomString(), - created = DataFactory.randomString(), - ) - - internal fun makeEpisodes(count: Int): List { - val episodes: MutableList = ArrayList() - repeat(count) { - val episode: ModelEpisode = makeEpisode() - episodes.add(episode) - } - return episodes - } -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/LocationDataFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/LocationDataFactory.kt deleted file mode 100644 index 0e13a06..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/LocationDataFactory.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import com.mohsenoid.rickandmorty.data.api.model.ApiLocation -import com.mohsenoid.rickandmorty.data.db.model.DbLocation -import com.mohsenoid.rickandmorty.domain.model.ModelLocation - -object LocationDataFactory { - - internal fun makeDbLocation(): DbLocation = - DbLocation( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) - - internal fun makeApiLocation(): ApiLocation = - ApiLocation( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) - - internal fun makeLocation(): ModelLocation = - ModelLocation( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) -} diff --git a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/OriginDataFactory.kt b/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/OriginDataFactory.kt deleted file mode 100644 index 2285709..0000000 --- a/app/src/test/kotlin/com/mohsenoid/rickandmorty/test/OriginDataFactory.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mohsenoid.rickandmorty.test - -import com.mohsenoid.rickandmorty.data.api.model.ApiOrigin -import com.mohsenoid.rickandmorty.data.db.model.DbOrigin -import com.mohsenoid.rickandmorty.domain.model.ModelOrigin - -object OriginDataFactory { - - internal fun makeDbOrigin(): DbOrigin = - DbOrigin( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) - - internal fun makeApiOrigin(): ApiOrigin = - ApiOrigin( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) - - internal fun makeOrigin(): ModelOrigin = - ModelOrigin( - name = DataFactory.randomString(), - url = DataFactory.randomString(), - ) -} diff --git a/build.gradle.kts b/build.gradle.kts index 8e0a4f6..7405bca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,26 +1,8 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath("com.android.tools.build:gradle:7.0.3") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") - classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5") - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - - -task("clean") { - delete = setOf(rootProject.buildDir) -} +plugins { + // this is necessary to avoid the plugins to be loaded multiple times + // in each subproject's classloader + alias(libs.plugins.jetbrainsCompose) apply false + alias(libs.plugins.androidApplication) apply false + alias(libs.plugins.androidLibrary) apply false + alias(libs.plugins.kotlinMultiplatform) apply false +} \ No newline at end of file diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts new file mode 100644 index 0000000..bdeb451 --- /dev/null +++ b/composeApp/build.gradle.kts @@ -0,0 +1,128 @@ +import org.jetbrains.compose.ExperimentalComposeLibrary +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.androidApplication) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.kotlinXSerialization) +} + +kotlin { + androidTarget { + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + + jvm("desktop") + + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64(), + ).forEach { iosTarget -> + iosTarget.binaries.framework { + baseName = "ComposeApp" + isStatic = true + } + } + + sourceSets { + val desktopMain by getting + + androidMain.dependencies { + implementation(libs.compose.ui) + implementation(libs.compose.ui.tooling.preview) + implementation(libs.androidx.activity.compose) + + implementation(libs.ktor.client.okhttp) + } + + desktopMain.dependencies { + implementation(compose.desktop.currentOs) + implementation(libs.ktor.client.okhttp) + } + + iosMain.dependencies { + implementation(libs.ktor.client.darwin) + } + + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.animation) + implementation(compose.material3) + @OptIn(ExperimentalComposeLibrary::class) + implementation(compose.components.resources) + + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.kotlinx.json) + + implementation(libs.moko.mvvm.core) + implementation(libs.moko.mvvm.compose) + + implementation(libs.kamel) + + implementation(libs.precompose) + } + + commonTest.dependencies { + } + } +} + +android { + namespace = "com.mohsenoid.rickandmorty" + compileSdk = libs.versions.android.compileSdk.get().toInt() + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].res.srcDirs("src/androidMain/res") + sourceSets["main"].resources.srcDirs("src/commonMain/resources") + + defaultConfig { + applicationId = "com.mohsenoid.rickandmorty" + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.targetSdk.get().toInt() + versionCode = 1 + versionName = "1.0" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + buildTypes { + getByName("release") { + isMinifyEnabled = false + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + dependencies { + debugImplementation(libs.compose.ui.tooling) + } +} + +compose.desktop { + application { + mainClass = "MainKt" + + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "com.mohsenoid.rickandmorty" + packageVersion = "1.0.0" + } + } +} diff --git a/composeApp/src/androidMain/AndroidManifest.xml b/composeApp/src/androidMain/AndroidManifest.xml new file mode 100644 index 0000000..b87d944 --- /dev/null +++ b/composeApp/src/androidMain/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/composeApp/src/androidMain/kotlin/Platform.android.kt b/composeApp/src/androidMain/kotlin/Platform.android.kt new file mode 100644 index 0000000..4f3ea05 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/Platform.android.kt @@ -0,0 +1,7 @@ +import android.os.Build + +class AndroidPlatform : Platform { + override val name: String = "Android ${Build.VERSION.SDK_INT}" +} + +actual fun getPlatform(): Platform = AndroidPlatform() \ No newline at end of file diff --git a/composeApp/src/androidMain/kotlin/com/mohsenoid/rickandmorty/MainActivity.kt b/composeApp/src/androidMain/kotlin/com/mohsenoid/rickandmorty/MainActivity.kt new file mode 100644 index 0000000..bcf405f --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/mohsenoid/rickandmorty/MainActivity.kt @@ -0,0 +1,37 @@ +package com.mohsenoid.rickandmorty + +import App +import android.content.res.Configuration +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContent { + App(darkTheme = isDarkModeOn()) + } + } + + private fun isDarkModeOn(): Boolean { + val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + return currentNightMode == Configuration.UI_MODE_NIGHT_YES + } +} + + +@Preview +@Composable +fun AppAndroidDarkPreview() { + App(darkTheme = true) +} + +@Preview +@Composable +fun AppAndroidLightPreview() { + App(darkTheme = false) +} diff --git a/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml b/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..a571e60098c92c2baca8a5df62f2929cbff01b52 GIT binary patch literal 3593 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 P00000NkvXXu0mjfP=x?Y literal 0 HcmV?d00001 diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..61da551c5594a1f9d26193983d2cd69189014603 GIT binary patch literal 5339 zcmV<16eR13P)Id|UZ0P}EI-1@)I=X~DGdw1?T_xsK{_uTvL8wG`@xdHSL zi(gOK!kzzrvteWHAo2y%6u%c~FYnJ<{N`T=3@w2g$1Fm|W?3HbvT3QGvT;S=yZYsV z;Ux5#j?uZ!)cIU&lDjT_%=}{Tn4nc%?;kSe8vq_&%eGAXoY=)gfJHN3HRxZ>B(Z_MschsoM6AUCjPu&A03`pU`P@H& z-Hldo)2LhkOv(g+79zsWLK6F$uY^-8!$ow=uuO2jh2SxRvH;PPs;xr%>aSRNI!<*k zq54?efxFGi!}O%x@0qhGX;;FAnHp6DCoZk~0VY&zmNZ7(K!PJ_APP1drc`bP>0_;h z&Qm$bcWJm(}i`WLgp2 zB!Saf;inDgfjrc$$+TEt@mPcR1IsBF%ve$XBbby0fpkyuOahYhptv_F4TPl^cFuY% z?j|wKCAHsATwcEiKD!!=-Rcj*rL{kREWvXSay1%O)$IkoG9;U>9D$AX2iq+}=c!zK zW#~F|y=6S-m(=bSuBh7sp;w||;ji02=~j1>n56y%KZ-d`CU}*Vr4Kbx#$l%nQktf zay7|dPxqqVP#g?4KFBTpC4g94a7d(I?Axdoz50FWHg^b+VQIjj*168V!-BZvwln~A zbKH-RtH}*WGN*#QmN8LoJ=px$01}Vc?i>8J3A9hHnIyNX`EfxD=_YXVIKs{VT3Ndn zW>tOBQlZBH$fP_7=2U+P&b2>w91zzwom{tMxdOJt%p6O<(sru*9vm-yM{=LrGg*A; zdzO^ZUi!GSIH4T8kpm@-mto`OgS_RuFCT{W^#^#*lhAo8$9JBR$l9jsaNtH3yDncj z9=-2VI~SII2{y5Q#*d6e5)(5m5qxJ>5ez6o)AC@Dmht5wuo5#@bKJK+ClNCgSImHK z-n$L4f1hQ)kyUO%%{MT;DuTBj5;{-iWSt||N^Q6Z*Y7p3>zTDvk2$AzYh73y(Ykaq z-S$a`7~Y)6@=WksXsXwxd#=vLpuN{KnDUhFcejffqj+47gj>yxu;Skx*L=&ijF8^lE3`V9ohnj~S&~kFu#to{@S-dohp8hv1H|3H&ftNS7f~Utf0s z-0Ba3@0BRndhI0axt07RCPdAk(OH`c?f>Mvkw)i#6?2gwcRS#Z7G zd>2F_5wA3$3sv9!1Cnl?gV3unFu8II%&++xD(_x{jN2uw{;mRg;AZ(A*EBq*^_OPS zqW3b$^)#DVy#pT1?REno`cCElZvG#G)QHy99*{=~0lSF3y@HHeTsgFs+5^r|WbX5XGTV4F1VJhg!y=hf7Reuqp}5 zpjo-u)jNf=s&|4cp{$jH>RjCOm6?Yz;^2*JxF>3UtZ*dKh{2k!N7v=kX)dSt9Dcop zb81lcyzm@k@zO&sTre7HI`lsiOGC;R*6af7$}J)ahO)%EGMpu4HrV~jI&WLG9e&21 zsJmTC9+#u*QYRowFVdIvCjDi%>vNHH^;Vcw_<5!BNaa2c12vZv4G*(@+qhJ4jaHo2}dFnxWlf-cFM)5Co`@Hf~jXV|1r?XR4QTQ0IB`3a47oVt z|6g6V5B_<=meX43`m1qB(K;T<3&^(kvxbr0HY3{r`e4_B5m;#>1JsFb9^)44eq||r zPuL7M8yn#EKX0t_p#Y8CWhr{I@fJ*t_J%S09bnu6C)j^6u}gryx)1{z z$5(=Sv@^^~4S~O!WMB72Qv<9l`<`YFI~IeALT?Y=U_MF;khm8cvUXB`qZ0oP2Wc83 z#osChA)h-mVaA)Z1=J9Z_Mv4EQKU`0Hs=d~uWLHHTj8F9fi!(vsQuh;Y9yGaXi_p3%9HylQ<{^u|E!Jpr zY4t0U3I+e|NG9!Y>09{qPVF-dsPK9j%*YIZDH(y_R=OYc-^rUv&#w9c?Be_n6N?s8 z9^Am}C9TAD-W?gNlC}N*&tK0ppev0xU{3z$pqt_X^K-X=L7_MAVAb%vKN#(G4ki|| z2CFZAwC7VR2B_UZ-$Otf>JRYdBF~DDeyfUhfnJI$1Eib25%kY`Kj__9fTqtCfnZSN z3+h2LXA+B+vx;J0>)HR4aYLq;ZoMM!gxQvBC!T3I5(z4a1ie%O6wUzYWD+DFsT?SP zO_=Fqx?LS;{=o=h(dLy0j@WC~g~8Fxg5;QT4XloWxSBkOtLCIeEb%q@kX~C136}~W z{!;!!sV!(Bsr5yWTz3}Y>+pMBAtcndmE_Askap!)NVt3&60XRQ-_JnO?`I+V+IdLC z&xu#1<7WJTkCaZW%6ugjd1<_`8UKkBlY z0Le3HPfsN^POO44|8)?{0Y@fde{uqwC=bv&v>e7pE@q z8(`eg?mj^_Z1R%;MZ&a)J+NoLmJOajThV#;*a*1Wppyfh8O(*koU0dg@3+iTmx-3%pq!1D#A~P}?85fI(%ICB387Z+3225a;)w{qpIRI>qdBW1z zFqn4S2W*aeflag*Oo{OpORNt}IpG6SPx^vWVi?R%2m#ypO<Q@c_!eeohr+BJl-$n%^@rJc zVJrtCu`dV*&tLa~{pqb>e+K0&?Y9Z-i?)H~Pa86@&HYs@Enk**Wmz8;Un@HUbREg- z1@g`)8lLw9tyAk@>Tz$-j&g3}R?-3alM`NG7VFx^t)v68d7=kcC;PQ=D@iaWF-&oT zIoY3qPO3`_w|WqasawzTfQ4rwKtIO=-3r|-&;7n`p(ki!T?3by%%?VMEYXl}}eR0u~8-*>a7egC@(77 z0ebnKpj+S})JAty@v{!0HV(4Wd!;iAU3(}SjHJgO!_=c!#v7LSv(=#;ee_JLNvT1y zx^k;{AC~8|mjp6EsR6ujDCRIgc?gIH4#gY;w46o7Xh8+u&ARAjs=MYV(Zd|>5l<)I zq!ydq8;WngK2|GjL#6ng2SIa3pUo2_YEbJuhcaZ!bJ|M+3DA@@K^wP{&U1`1Ji$Jn z0J+J8Lovr7-wPaycQhMdw>~yi0A+MG*48?Xw#eSAWmkVP<>noS@arM=%bUAyX2#;LLWhoZSwe7Dd3P#rU~6 zqIuD8I~kmb8|JQ~HVif#{YH1fk!(F*8$FmR9;Ul?nv-6Z`z>y~#uj9EWSuk(aOv(_ zC;72FM|Kh@4$2eKFze0?lxaBoWI4n7 zst!_O^F5Dg>)A*91N!HK_XgOEvq9IWqHJ6I-g`jDUdcqLQ*%Qw&++2TkjbScru)Lw ztRP-E6myJoykY(s9EfsBAmuqag`OgEwJ`@5SG{TRkuB*wP^|l7e+#rlT(7;8E-aa$zBqnCzNuow4YP46D)HB_>({al(7k>W(V`ap_pTmi-6FrbZPj2 z88Rh-TKHSlukBAMzM`m2y7tw3yq41@CcU9CjNT?5i1N{h&C`OkQeFP0?wq|hUnXc? zTqECW;WlOAY<92p@IexgCuZV676I|WAuBP?^S(d-?6zjTLNCzCaRc>Z&VQ?TTWv<& z=w;r4oUTv&Ut@YGXbkApYlt!}dK{r-q%vvrUWXX!HRzc*`{#wqP@y5u%w&sYz~Yxm zWac@OGI5lj6Cx81rX3=h&oL?Rg#|_1(N)*MhhNNzRZ<^HFYu1&rQEAO>G(9@NN+Fp z`CuUV_F$TGd)LWu(YS+4(mpNPE;7FuBzC=uKoNVag0Q4#2BgKdwz1Fjw1=bRbtuz;rX1c3LE7MhE zk>xL(o*OD8C}=S>MarOPAw;#K&R0K-m=)Q7nkG$G(2|v5z2ENr&a+@OeA^33Ix2lR zwf~Hn)lLp7ENta?tmUvR#BG(^XESLpd z4eagIqL$Z>+GQU%++~u_tHb-5aTYVIm$GtyB^4z~{+^5f5_*9Ky1hSQ7WFPIKcaxy z=iRrAK6D)Kq!YFv%y|FGsF^4IbEc;RmRV)`Uzwa6c*D9N_!fy(j^M_GIFBpi53en= z*uO5v;_H=B8h$gwROT5uQ5~GMP@RLxYL!Q_LG|Pfr5(4%amYp?ni6?hSP#J z>irZI7001yQKOYK-kbQA?r=*I`b@|0oFR%gg(T*i>$J5J1p#4~U6HrAJQS4rYPAy^-!I;eb$Kms1miPp znxu9z(fBqhs4PKV3X42eMfL^am?*ly8X6;V=hyFCxI1@I!=f1d!=3rfz31$AzVkch zp7VX*?j1Mo)#oMtMB>2sS>>u9y+{y;Q4?1|^+Uo-lgUx>5e@WdRZozbvM0%m8E+E& zjRkKC_X0v6qoZ;DkLX5cPgn9y9K?woG4pg)e7W~$bKAG=@-t=M@-yXF2!W6TfI}+35(&+V>#9m}{q7V15swrfqgQl1VStksa9&pOgHMKd~-Qm-SCZ z?FUZ`Kxmd(TGg-o^jTfLhHOaM(jG_+>6}EL#`zf3T%@UpzZWCQyq%NjGwgI>rUEX| zm}93Sne<{E*^&M5Imr+C<9#y@UWRncZce-7vTxrjO={uAC4C?NeF@U!V|2oB?0Q~j2J#&otpvOoP5rT|)SY+M_K^CyIeK-7B zjf!=V=Iu~0vSJ;{q!;VRj_ileNq)#5-4h2NV-^Bh)V)r5OaDA#0B)bInH**;>{;Bg zn;dcx?eBrGsACsab$$pz7O=MSV=QdnVW)fN`UhCnvByqFGU>%SvLpN9bCMtONB6`b zvV)CnE$*G+NC5N%Ue+FPdKJK{0KSI+q^yaogge_O~^OwkSt)o zr543qrFOb^JO7R4*Wb6(kxY6)j$+t-rwpH1svnt?{E$C>9ODpmeJ2*R?r^+`ef2p# zlrfnhgOeLFL7*j%&-RckV14I*Q1i7O^Vt$9=;oPWE-_fv=$bgLLmaw&*vbgESe-U?cKQ`Rhht-`Q@p}56 zi0!jf@^&vp4}`GVK7X$j`L|BtbZ-+nzU@L!e;>Xb=m*DfxIgd!-Thzl`eQv>6y83K zYWCE~?u7>sWggs&4EMj{$vO%ePj+NKrUB4StS}VxP>qI}w{fB7A`l|^9rj-kWJ0*P z7$4oKVA<^(6?p+L-Pr9lOM&}fOMOO2E^!4Aj>2KV> z3x9pi^ACWQ!M$wB6qD+--bTRD7_2y#%Lnsa0rd5MgB4YU2rg6NX5U@A?{-};fmdtV zvo`T}_W*5J=KHtpOM+#!z4uGp>a#dhLSOx_8y)vMp}hv zV{)|CM+=&F?WH|fqAf&(vH0m$p^-{x`|Z-_LS8_={s`t&svx_V1ZivP*!RHBo26*H ztsjB`x-K&sy9|T4Loh;j*No=7CN$nP+R$P#LuYA6lf^WMZWEfj&A8HY9ZfxE8@3sa zA-F0P(y9b_)Fs06TI$#aAZbxz`mt4T`sD9Cd_LO*=L7%1w9i&z+Cg?b^e*JbHpBDy z1~zUroKLKQ^XF?JJ+&FLOXJ{DvK})^H(utKf2o;qYp>99fOoC!*nX zf{{A04z8cChwG{Jke5co?`#6xN;ks&>?WSPrzRR96{(n69u1E#V&HK;7M@jc2&v70 zye1i*wd^TeOys1EO87QsjP37%NPRH^PA6c&aU}wd#lr7+Ec{Qz!T)4DB1%*UEm0z{ zG!cPkk`Qz*8R42VM3t)%tWmP8s}RhHhn!Ex-)ah>s7{BXCIcZCG7)-Fjpf>6L^R|g ztRV;U8nd~1O}SX8%^mw6^^z+p1ePSQ%&)@qBMe7Z^JU|GG8&STth7$9h0E!6eA#%N ziH2`k0%n}s2-mVreA!Uu6|CN=Y}_kj;9eEWmyMz>gKy%Q7ugf5PvAVXNs!eh_Bv%Q z9Q)H~WLpv3OE%ibQ_Xvyis5TsAWtTDC$|6)+J+R z9qR*aBIj`_8FCiDAD>46d|zBi!;G^VZ4K*vIu_EBEp`nnD`RD*Ng5kG1;*Ip5>ppd2QR+CX|Xu zO*%p~sR-1hAh2ACpo*;sugpMHbq?mRnx|zlxHcUjLk+878CPht5OOISA&uEsp=0yu z3J|KxL-^%9F8pdfA})=hi31GT-B0`9sQ1+jp5*MZczBkvENfyQDUX3qMKXff4l6w$ z&u>y*)rqXGlMzv$!x}c3)qDzHHu44~BAWBz*TjB1H>X0TQ*qvx)8OAgfA0QeGDaV-zCDn$*;%0^z10RJkbUBl8kA6B2mmkl*6)jX9=XmbuDuYzYY>jRyV zlU&{k?*>)x)WXG6pBRAf(!go^;@|jQQ{VM7KHCe9fL1ll}^JDk+PzN|`LJh_}kmCs^m#WLmwd60NdohMFX+tTx#?Uz=t1 zsZ;gJ>y=jdh2(D61FMh!!sRV0pYe{qseFy$w-dZ3`%GNms+bt+%wy8fRSd^;PKt>^ zgLoroiVYLzIw>a2bymE=u7rs^MD`1u6%(YBeTfTka`;^_4V)4=j#Q|q*LzL~C5KRdRgR$D<-wqU{rxAoiE9G_nq^fd;fFZx%V+( zz=Qq)42*!CPde(h*x_ei!)?Zrdj~wOKN-lL5ERP>b$3m0PBz57LG|+FTE*)q_#JiK zjwLqG)?)=8V9NSeQ2m;@f%Vy&XVh;zHr>3z5M)~YQ;>O0BNg%;b$AWO;8?upkq3fH z-%f>}Hx3ClXV2mrRuu}2swN`9H>e=Ylmj8AZ2FxmsKaaQZ@dTZMH{oOWj@oLkB9eX z0v>JC0@V^EYM!+CrOb zPS6#8Soy(COrAc)$=#sP5`k%CHc0@CdtFKk&!AvfKq00z5M*549vCaA!)xsU<2~eF zw1KwT^eI~O(Vg!H22W;ag}YJN$~vEB&S}Nj>kPEN0dQ9UZM9DV`Y@!dc;FzoH~Jbf zHsP#O2RP$|0yt|AEdXMR(u&w-^}e-foBwbS+-k7ohcCCyzPJS<>o+iw=Jm|<`VD}x z@Y3fn_u?nO{$^#~#m^w>;-_8osKaZW^=JcavA@v=`ud<@3oNSt_jUqd;O`59lRQ4g z^p9sZY=%(N8b)YJXMBz6z{^ZhIs=-nAdgDqYkfi)}sxy#nquN^!Y*k zX7D*@T^rba+ewpl>#@T}~!e z6KGF##@dBCZWrY9Y1E{wVP$yS0U!p7rB)7;G@>QlQi+Wy_{x^SVdk}U)9Tj&kyiY~ z3Nf?cW3cMlCHcy3*m1KGBI?)M=&{<&ZTO_ic+}xFu8ve2*m+Y6(#yNLj7Oj7o5d2| zunwktpP_g9dg-%WR)LKu;C%Y50COe~Vf;y(fHIeqGZGZAzgby&=_}CRy$Xwe_|is? z6=eni)_FYY@ETVqy1WAn#KzJ~Uv?RfKG8S(8!`Fm)4@xV7-hQ(oYFM;yrPihKD(4X zQ)n$@UdspdFXzCIL#6&wD9Drrnx;Bx18wz~1Nx2!D1N$DON!WBpxD_5gwILEoBTRu zQ+uD%X8<|m`H)RPNC}-h46DfR9FSbz3IDlK2KyRyP}yXl*Y`A5!xz^}=(Q;%2ppSn z?Eq9X>8XuglbG8(8I|CEM%LuEYw?)&hZ|d#{7x&P1fW}Jl0{OdSC@EY7hJo4>kk9(ENBaDa($pr^v%^Fw$S=) zn0hMRG%P;w`St+Dte<&1AeqX!a_|U+21kp%s_eCMhQ@_*7pGKw57~atX z<<1)sXvnzPR{)rBST?ziZ{2Nzs;lSWPV?PeaWtZ-2V?7J&a* zRpZ<1-yPK+fc>^PZ}umE)T?>W%(U1zU9I~T#%+tDpUtf;eS*g^YtHTl$Gj!5=G>kx z*Ho8svF7&~z*}k4#&qPsmJf#c*Jk|GTL8Ys3|cNb1KLrmhADXx`q|Qt0C3E9lNzR~ zQy{lN)8+cP+ZVy}gdBYIX*~uYJf-~kjl|Fq?Ews1$a_A#ZcVRAthl-ter@SWllv{r zaQ#kWzh<91)7S6bg8SW+-=^l@Kz!ya2tA$AV-knfq?%rw`pyg7e(tG=vss#+%IJFy zn;`GjiHDxJJ;|<18VJ!SVb0kN^gO9^84amWXbI-Q+(vGYk5=}1PZSC=X2Iz@7av&w zH8+jmU783%<#KR6nMiWN_CY2%82dHBY)7$MTZw^!f|w;30PVjy?F0sZv(VW5>mv)` z#@*W>)FhJtQoyN91g@u&+FBfJCC;aS>sRwuB4(RbVqDe?2hwNU?yi{=k|Yi&m4VOR z81S}Ac%Brd9FTxdo(Oyo#DQ;qJopwQKzN}X!Vb$ocvuX6hb7>5gh){$gsaK+w3t+o zVriQkONM}wWC$-?1@Bjoc3C5bKms_hf=Fcw@XN#yRG|PTjR>5|V^8cg+X;-3!2B z&jR4@i-yU0AHn$ji-;_S@duW``1~cnKNJg|hvUHU&@y6YIZQZAGAz2Og{Ah45AaZaeOfHOp zfFp#{MN;4&5dptQM1k|w@!(HZA*_t>x?b%<)zVce=*$jPeTgotF4)_))Lg;=8`0tAYk9{%Vxt~a0 zEO_O|!qkIO2stDL??dt6T^J8OhZDf3NKER!oX|)KzUo8}s*^x?ObWshDFLs7cgr)t zPa^|=lC%gsK&ybT>NJ>LlLLV|6$Bk$)f#*v6?_Wg4MRu0G`!o5y)~jgkKOj67|&ub zVS3us^Ull3vM18nN7^{#E(C{tizsb8^2zcS#8BEe7A&QdLGd^e2i`{$C~YPl{fJQJ zBT5@VNdowlB~#ismBqGEh6ukh5vCkhfm2ny#aSn|OsWvUsO<1$#Mtfm5GSIS3FmZu z9jk;HvcZEaxx?NL@Z<9qgGWIu@DIk=fJe@I6p;YbVjJ+tc|oZd{K@Qd!6WAd+9U|k ztpew&gcg@-G1%uWI6<)egYLw3Mm*WusoYZ|5`#ls&Pea$@d^o`wWl2!=EOt-0)bN@ z3F~n%mL@D0JSMEiQ9>!T#0ESjtVfvy0tj`u;7P)Qpo#=go!UxfA0`}Id4JeKegtB3 z+%nIuKSzs0$9^_PMtu{p~z>_4uPqCy+ zwZWtfAf=NF-dP(D9>=9j=*cvTQ@IF6uAZKbnEE_g?AYnkC3?jpZ_)LX$SE zDi!#IGJ+~82&$zNe85Q+6RFDphfkw+AQpQG=u#o1 zCXMhuy%ig|$ePs<@=e?Ug5jTtrAOZP@q*(iA|sr>U9{cp`(&WU8oj*W;MJypP%9@1 z8&7G&O<1oI3HX*Jb*VO3+XJhW;G~VSV8SBjkv0xn=ito0ffxib!Jt3%mWEAgBEv_2 zJTu+(gyf#}HIOCDnB77Guyi>aHDrNrmCOpfBVoNr#q!liyHp#msw7KbwE}@#u-Z&4 zj=ncCb6N)ad?4^PbQ&|}Psqd9=JVfmEL^U`)d(m24=}H`w5>?Tn@4&wr_ZE`$W2%; zGW){vWD0yzxro&DIL5gmzQtRYYzeMWp$;5&FVMX_+j%DCJn{LvY13O`kC8=S5O@+W zdi2^EDS@TQdf~ZLu&xLdo7b$ha>nVnn3+(rl9^B%!}wH48NbS8W+DOZM1mu9X{$CQ z`MvW+`jN^|1+o1W`k=o4AOD76t-(mCm+byN*ug$yhIrzEWhFeFjI;%An`T}yWasFSq8TBU(BUsr`Els9~96gNDMC0z9>h&OoeUa6h1 zHEPG(itwbDg!X~t-ceQ?Pg9$+$MZiE7|gR)AeeZg?f&+h<4~93{1<%2`l8@>)ZsPj zm=~@0*gf)p_ULX!5X6|BvOih#gk2r{|A)U=){M0000mR-|nJ ziD!nlM5WpyKdG{c3k2M;jXYyyVo*^yGIoo3`~=S|F7P^2q1SWS$X&WX;`m|lvakY#7qwtaxT_5#?fq+k)xD_wHQ zyOv!iWuFs&s&k8$>66s&pN$6(OHEJH8Iv+e1ce=IQ2k}QWOKrE(R&G&rrwRul5JO? z9Uk8YLMp2>9IqF#Te_G{OqvQMdu+CapwA4T<&Q@QcIv*Lg9wCU@r|C(t0{!0uNy}p2{-c$-u10k!W;Vg~%I&@z+#7Zi7r~hD8!> zpn1}&ANh%cY`4tCA32CA8i#xOs?h4F_7zdAHMab<*W)CuwR|(~gd5`m3bQqKX^YNG z+~{>s$Jk%6cClss$H84jVN#H-lJD2DGwI}SA zu}tz|ZwBc|Pw=EGw^kh`Vk_xMX|KfNCGdbgab3{y-S*BeH0I5?Fmdh355OcbEk&^| zvJH}xPR|SFnmgsUkXAZ4wj<1U04=0TZjaXuYB~;x?~Ljrb98Ioa7$W@Q2QHJmAU3m zqlJ2~r0VR++WqVw;&dIr@dIHqjUh+ASQh@B(NS@~cD1|dsV_-;UPjE8^RNw3E?oOx zSawJ0BrAl>2pdY6WexcT5X1q?^`Am81jG3nOs~fmQ$LhX9bynlAH4$-4lBA9QiYq@ z87)AMgAz(4!fMjm9M<0w0a6v{tIV^NELObpXP3`b)U*@x89Tb^oO+db`gC@e(i|b` ze67ZZ)BB~r(*Qpqoo`Z}T1l_aj#u&OY)!Dzm}f9df7x`HDRr$b;S`>(2aRx?w^7$t zp_L2SLwiLhm-FJ$ZHb+HJ7c0JKl0+sH@!SL|IheR2Of?`TP?pRa8i{~W;*EZeiU;! z5qg1lRW#x}?|K&Fq6|x^H3Q09CRZ14A}?5rOE%fsHgbZ;pRpI;nrtX##M(YnKkkk3 z+~&?#V1fxYR?-#{_;rMDS7${>_1W~iW^pf+R{8V$q~hG zUj~ld*aJ{`0%9kHw*9lEZDL0H32F{V&21_p^|9KQOZ%(tH&iu#-3N2M1Oqu=%QMi) z3a!@quYHxs5mE$*16Q&)2UBmDU*nJw+cVC%T6}3p3y>DMkb|)L)lti?c%_LG1@z1Y z`O0Nc)Qe2`t(A=Nx@S-67lfIMT>Z~C1iCb;(6G!=-@6n{h*4Lbzb@xt6wbJ=GtlqPq%4|UJ~huHD1cmeY)$p=}87X%EjT<#QNXdk!a+04QLozV|jq@$tbmh zpao9vHJHhQpjvywl(1?PE{BS zfR{NBD8e6C^$``kE!T9P9nZe@25vZLg&y^Ao*qb^nTes4#=LOmYXkDsiTF=zn}0jrbE{YJ2QDvE0x2)7y(Ha}6$KtxlNp z;n(;S{ex!!X?=Ij-kdhogzEktXGnH|JzUO_edSyAXRv4nLYTwEfl#KVS+7%bqIYCP z&ur^~ZSZtANr8eUyQne{v(gw++&~%2)9p(*3iM+2oFo6$4_%fmG}($R8Zaq{=*v4` zV!nyJ@5vIXQ1m?j1P)8`sLf>nrc_UlatmZ=)H+st(SRps zxN#&CRCYp(79mnAy*pBRv1>hmJjf?BH^u0slOl&xgTlsm$Om)hVJd^1pw4p?10fzlXzO(| zbC^>xs!xnAKfHePWTo%hPXFv8`7IYqX4gT` zQp(=7i+KlBm-}5**KPuCw9u!rR)J;9#3s|m!}eO2EEDB?Pkw-lW*+C<{DR2Le5qD; zzW@8)0)O3mN~otlX@tuhMxW;eIGuX+$rh3RWDgY7H8H4MMK0V0;bN9|!@w63^l3&5 z&0)q+q@6rD=7qQk$KedGU)PVDaA-g0fo}fn9X~WTc}y8_Lj%CE2dVh@8NOLV10^oF zQI_gsGrQl%rRNcT`SgZzAFOvvC4dF?AeqWY?4l@*#U3O*MGdG^xOm5JV%3;SOATnC z?9tAd{*w^|RtEk`S%@DO?b=lWR>)||^HL+is%@`JzWz^pKeH;4-@qzLS8dlpcx49nHQ47}Z2YEuTDZEA(kW3fYY_p}B6cIFk zMbt8vgs1oug8 zCnR@us&d9lEL~oxDKzSww@MWCZXwy07+^2K-AXe{GvG?+83e%j7Yl=f%Wb4B)huao zbP=@84F{aNVYG1Qhajw~Y1qVPFM1Qkkb`Yy&!y;yTE(C{18v*gn>iwt74810m`a_j zaeX94mEQ@K&M}<#Z@w(hKC*E2WHWD)aW;8Ua;S+nTxrjgc~uYuVX9eNx@n2>nQ}l) z;B1~Sl1qH^^=wCgv3{;zvR7E`t1eGiP7&c2d+p1;-4J!)xm3Fy$-)_obcQRPY%u7? z7XZstD$nFs>PYE%Mk7Z{QrB2riY@bl%aA*O>%{wOH%T-++P~>LC$UivlwLe&{{}*+ zkbH2ug77!!3m_rRpBFHht_jt>Us4q($OqsvHD3?|8t7vwAtJ;_*cvb{S`NuWeEIon zjsj(8M}cyEYQ>V-6XE1Hk4Wp-sts3$%7Mpv9*9VOz!5|H}i>_1X} zG`$FAG#B1$-wY#f-mxdT>FlkZLKBH?LVAFB!E}EpL75H{6wBvM^fdB%R?-j~0d|zFTA*n!Sbq@R7I$sS)Sf>=TgS> z7DkZ`m`^wC_Q@rUNntv|0Ijbf9@edvA$M)+#jMo`0r?s#41#UZ0l`5jQ8RIPkWYkL zLuSnjlMf=nsvrXsbLOTQ^D;=vJ4mu6B%p$6II+3u_iquF#Dv=&_{Ne5M{*;lK;68G zCcB|s+9?b}BBHf%?-TpXD^VR_P2J5myX1qdO&uW~Rc4(W7+B=mt#w&%j7)yuSIH`t zvogKN-ARwD5bj&d;OK|`hx40`q@@8|QhsDpp0fOFB|4a zU1aM=Yf<2ymK zU)xMo{8RuIn0NEhLK+-->qo3hthYqL6fpI~8=Tz!8VDrj z@vG(yaO``ZSJL~M*f_nb>_GJJSMJoZ*88oEkhy(K3iaPYXuH$dX>EnPP{xi--@Dwg z8bG_SeeY6%=g@5Mxo0Doc1WM#-}0nC;rzZU_NEIRnJ6u}J@fBxdZ$f@l{?MD&mg$S z$EPCM$0zZwcWT`FU8Ej^5NG;)p+aG`xn!?$Ve)&}j!{ORq1@*_ZMk}L0Xz(ns0%wv z9I$7!d>;Njr6K{E7`|9mr3TLh#}wtivvU+hRX$+hNoyYhzm|q6NXEYB#;z=!b~YVO zWr0qjXwDrkt-=^PD4HVWGMq`hmTMQky0!3gBy|fkG9WF~kSkw-QzO(sS=AbRuW`op ziGH!+lMV1j#rCixt9)sG6m~TjhW8@qc&IPD{BVWND zE}dlIZ@O6{V18XdiKR=l<6aTB2BC&kpPu^4(Q%5cZf_ImMCN6)=Q;MHw2-oy@2Dq? zBq7jYByn6Ri}-6uueQEcae}Jfz;iW9-@@@%gT6?;;VkD{|RNoav#$0VNE zk286ieB7O8wkeB~4|tO=-Xbmsf3}F4F>ZOgHfk8otsKVsWsAHTSaa8kixa6o-Ri^V z0)MR_rp^PW%$7L2Smf5N&hU;cW4ZGprO>fj*|YxR`_GR&s^#MgsOp7EmAx&@#MrCd zyIaPnnh;UNM5d{7{h@D7*U-~T?d!MX93o|1b~=jXSLmU?qT;fW${(B>2Xkjm*GkNF z&(^d3J)=9>N78NIp1Mp3lsdWVqBKFPu2q<(dE3}t|E*)2wDb9~gCECHE8@~_#Vp&a zzNrs!hW)H{u=fDT_Q!n=TZu}6ReD;sxxz$>nGv(gZ_n! z;P!3tj(sx=w_Y;NUw>m_{`wMv#{|y_Ub1-3epZZSuq+;f$KpBgTzJmvqStkVy|*s` zM7`DU*~KB<%nCwg%`Dow)2uKggWyjBFe?a#HD!ljS;;<_ksr(p*2VkiF?cKmbFM4& z+~gW~t?C^C>-4Ya@sh;rW(KqwmFF{kRIbk7OSAYiGH)Iyv5bNP|Oc%MLy< zDcH#LMkFZP`;8>w)lnA#s)G}RUX#6^Nq!Juov?0LN3Ooo=BM}OB}u$qk$-#rTyG!J zz^B;bZA%Yeqp7)&MS6V+P+bhH1J-3#$pLOeJjJ?Vou#$qz3BDm>Tz#J<@(Mhjmi_7 z8q(lZr3ZwQ^MZI2T3-Tiz`9_a=p2(RHcfeYc|LQ*E-<#K!H)(uQpJDA=KFRbjX2B^ z&zTu)AojKfCjgEB92Km2qTgZNNgJ>&+}zM$13Jk`OFz$h66yIRv;j;b%OxA!kOh!{ z1{j|kP)<-m0P^5adYGmR6qVz!tav}nFAU{f9?Rk} ze9L29uueS6V%y4%^VWky!J*^{34#uP%Shnt-=fStZCuKJPTch<3hYY{mD`mb1U}gD z;1amsISPEsZ@hON{O+FOT^`HgF?`EoU9e7k%VS$ZA4Y;>{(+=v#|7=)>72lM05p@C z>l=nWe@*F6%}wTW_isUE?vmQiY5L0f4cw@DRj`za4Q*f%)GmDJtIs&F-fRK z#NPcxd%r}G^+5pcb1ym{XeK%xC0sR@;7vKbU-!1>EH1YrnO^uHfJADW@S}T!n4&P7 zc}f`t+=Mbb%~5q!j!zDo6REPy_d$TF%cs;7rMc#P5jv-1ohN1X;6}Qco?h(4E396b z4+2#CKG#R6ds{#z6a%OdN=cDO+ zSNB6MEo%}RaJJt#Gr--XAP7wIH;5+ZZ2)PQo*xVzWyfefMOK;W*m*w^p1gSu_uu>h zmc{>5SRT!TdC?x;=f|>)nNxh;7v+D^x?r97o*&zaZN|3CDnob^8UMBp3@$qO)o3md zu(=HNBi60;vb}Ce^L*-Rf^16;LfF%5AQFk-*C#1pnB(`(O^{J;AVfd=jn?7JlPk1N zN;5&(m7HlLIAnIWozOv&TVA$b`?}jSX@0-5CgFueyP^26hw$jlpESk$t_46d^+Na; zt;52?UCQ%KC5*W6*q3Cp?s=7P%Tt+DPc!2v}}i**qIC%@o(7vVLT3(}tFgF&|M zI}>0c>HRsc?$T>x9k4FS7C;;wXL`bj2-{x>r%e<`$LtW96eZ|N6fBkHdMe8e9h>71 z*IyJ9BFd>3qMz*}Q-B4em(D8KN+&tDJ4a#donv&-1wASc@;`otn{v(aL*ToDoiYV5 zB=y`)yqpwu`(ic6}Qm@e#8oiZY&!zPc7LgOB-9MjYT=b_D(` ze+ii{%jnV|euhHe_X~@5!KQm*kor6iN?$*M-(Nq0r{yoG>3B(iBqH!V;xRF2cV0h+ zlD{57+_Nky>Vm>hFwR{szV>&8JE4q}!E55Rl^%%6FhhpF+RjIA)sIx$CNIVNX>6Lg zaT}lBuM7e3_{e9s=wygJb86lu8Y3X-&j?BQd0l{lCH|QMn~9LPf_3_7I{iHSkLzLr z>q`J`6zKit2@}Fy|A*Yl_J+6_die0BGjcblzAFJZn~m-u`s1&Juj@>@Ea18E8h9-9e6FgCSLoU z2tdrxSLy4X4%s$$2y)D=AxjltOtQzj$4T$B*UK9XSQo5Qy$HZe z#G>h$n?UQtDj(_dK&5~B(d^q>_Slylf<;B&3l|etP7%=cLwC@kcn|O?zp~^9$ar4Z zAjp>#0b>!Y8=p2{Td~d9c0T177w-|;7X1h&7u*jLj+?#}4@iW_%}jsWbP;ceBR;nf z{cc6TU1;d;;a(g?WtSH3g{v=$K-fTtmju=c>xOky)DCPbwi(;bha)oK3$2Uxf^nqB zWx{dGx6=~Ln?{`s)mu-<^uLP1jJ*6$ZA_49{uYRNmP!3~Q3DhJfpx<=PRrk{G!w+- zg^*LjSm&E<)w_3~dx#`GAujvb%Xey*3E2Vp$`%0A3>W^mMqR*$NSu#p8Y-d!qre1ZX_q2lFqDa{`|zQvh`D?!A8c-U)zpmgSn(T7Xo+Q#HYqVQ+at zVgYu~8)Tdt_)J*>U=HTWivop>Eq!($Hm4t@$a_+MaY6ReQrLX+I0WB13HM(l_h{dwhwH(AFj~dEdJvjn4WQmK?fF57#_2Q z`!Aj-o%}n`AA#;!TNrj~8O4IQAo%^oWBKlB`D+L%IS=|-$`e4%)mRI;mMTF1t#j0s zWrA?I4l|RAh>0(|0YeX(GXfkWIJ6j|ORp(ifUuHOG5NzzF9WS}t04J)ro!XOUOa@U z8S6kV(@QBPsJFxT5i$kn=lAs&6SCJSWfI2BCLdxl?&W~qFDu04BW^y-SGoXc53u0{a z!>e(x%iqAyS&{JdSr0Hhw-!RK{t7~&@?(W^a?V|u=V0b#KZ;)pV(5w(pJQ)7Ee4Y~ zFVISIq9dW!ZfLAaQKzZH)R60{`5-0`Ym7mH(Jj9^2V%HdRg+W$5?=JjT_}Eb4_=km zV>+6gyX5(O3SkWb!oNr-alXDEMn>9#R*DN4Wck!gfLtFMh#5pW-fY#gQ&+lqw@ONy zT?Zy;JMG5$@VcfVa53e5b2}9w>0u_AL<_(q#uH4h1cL9KlQm977+r9|R73~LwV+BW z0vZ_#3~@-bo}Ll7w=T&z`_e=3_|5ZwoB)qr{Q;Iq!7wv!9n6U*0%ZOIO9`n8IV#*O zPR30*<#3pA+=g;peQ};$Bxp&7i3d$bGk1yCI34X&_A_0d{ig}={LL${z4kpZLw2AQ zWe*la48wGRcw$zNj;=7hy%9$2HOCFREu}8Vupc(p_}O~SOm?NHrVBEdKRNg)u0duy z>z*wY!v4ZblzgqIHBBdM zwONuJo3l>5!2VA}#JvpAk9Gp>%asCX#H_)c&@x8?wSNZ>e}818zFaQg}6 zSRiAIqS^}MkIA3*Qxd#FYqKlDBsU1MpOwMA=a1#$(Tk@v-9X>JkcB5=Jbd{FJb3xE z^0Sxn@sO0oNt1hjUm9Lj;=!w@@c7lUDxXP1_Mc^76u%a6<&bHj*TJnsQthpiRE^nw6PFLEI6UO0mlQNdslxe-hwyukDlL8LcKuZ}1m z2A6%nGIk5t#P5I^(Y`Pvh9K6j3e4jC8N?&j!Gfes;F`9V)_rDDH6#bXtmHtLmBK(L z#sRcr7y%68T*Ty4#5;mchMQOfZex~qnk$U(pSv8n?I~E$T=v#PCOBx(<15YndN&2d ze9TaFFG%mUCk#Kol1VK{q!$o_e=?_-dE5hZk1U75KU=`yBMgT8VhKZzT2KvUgQrwzLXK* zj3Y1dho4&k#uwdSIvFi|$VZHhbcTg-8+nmW1&AdAq;0DdK!SYC86mV$glw;JG(Q6m zE^|HZmU?bLUEJ5Nt?DAh0-M@6_mMgk#SEWlv~vreo9-J>gbkxvCUivl?D zB3~@PC2wBjkGy0HqoZ6{0Th!@C)_wG0whQXkmLlK$xan`%c@q2GpM;wwnk3n+JA9k zjxj?mKklsBM=QRwJ(1X8j(7@Uc4nPq1mHtHnw_uDdBB9TPQ1uRvtt}y zRRDS9W3R6+fIRZ)WEA2V^&$s{?i(7)@x~~$ozM=Z z;F2S?^&HUbjE-V3CB_SuC2oV!(JnA1+7-sc5X2(fh}-E7W8&RmEF!^!!YEMyb{XHp zjSDAkC}7=!&-p&oMY~RxonOa?0<;nxVG+%|>ZhXYamS*PHZK z7VU?5(Sb1Y)LIJruwa;f#usLt7QpN?o(#@nY~PZh-l53~)tkK|Eq3EKAx3 zUTFtlVd5rONIas2$(vwN@@80+vIQ2UZh^&!v|w1A9t`H`Az+!l4FYcc0?RUXfiwG+IuR%c^6*fQvoh{fLW9eFY*y+b`~XW=0!dgAVER^3G&hAYot1h(C;U0 zdeG6J&uHYZr(w_LwYgcoQAgdr_-Oa;gAXkZ!W)m3ai=_v1oXM}j<4cHJ{5ojXcNO+ zc#)42?&L@mz?T>KIN^?oaf3xko8^-);qB-o5&?+$F-Uf=LO%9>;<$)Ll5>9UXSyA^ z>)5wrn;Q52N|#6-=YkH+y0jml5$BL8EiS0d?r59BA7EUJJ0V>$`Dk`9DxMhT%8PvL z^;Ce%e!R%XUXKDSPTHcd=X0KpZlVh;y-EZ~@eq@b&`xm{YNfis-~)?uns!qiMi*cB z`2IXb!6$0|rq(*wJ%D>uSzYfBn3T1i5uM5FmvUz(s^v(cz>XpV^FEjhuDRRBK!N-e39pNTqvQTt@3N`1sOeXo_%+ zQyF*2pgE!M99i{WEmBK^gMY%mT9;b zjc)nocBlX`{=9QLW8*x)90ibLb|k$W-DFp=zP^hHu$Cb|)wP_OoYY(%V4+ zmfhF|W70e*`6I$@q0ic>n~@uqqk4IsbR(7S-CL-%YK8k+`VBg;_%PmpY?L1;vMWBQ zln1xsNI(**dpnrdF($zk-`tK#G!YYXgTKTXNCprXN1WS2!lezd|XGF3$3y z3mzKhZ5V{vfEkHuO(Hx%;k$yT|(53 zW`PSTv5pj&)zpc1qPZQb^zAgjq9A@gdO8$j!o?m>k;*_n&Anp9?L9)ncsEer_Dv+= zVi4to;ileyVWSB*AE-2KI%MH_{{-AYY+rUrXj^iiLKzS5wk`e1yO+%PI0@y zHg-EKh~5ATV_1-2Zc*GuF&4*fVvw*I)}-tP_tbr0PJDawWCj*wlC>aq9$}e=`JAm3 zR_WWoHe)x2SaRkivJ0uehhS#Uv zmu`xPd(~R4YbWxzXVaEVhc7tmpE&-8FEvLvCn)3b_2aVq!61?JxQnY{Zlpg#E+b+dpCZAPrj#+O zxjZA3rWP=|r64}OL24xo)7HXhV)I952t?TP&GtE_G;PsT136&1_^3Wjk2DduNx2un z&>@E{!nui=J|98Oh9$la?Zb_*nsIArVr>$MZu#bRro?)|?Dzo1xgB=W#gww;mF+TZ zKDwHmw}Upn|JJ!^c5s_{FNsO_o&UlTUa(oKUY+q5hVWPD2KWE|yCYa}=1D8elVt1q z)I=0vZu&-=Uf`SCnG)v>vl9Y%CDw4l#eBXcF+H-#M?atOc2>a`>*<7xj~wXDw!PWk zL4Fkx*dd4`VPL<&85>5%*uO!y5+i1M$9**+YWmp9Mftnn>(q5H;u62y4iz9VkQe!g z@yVW*0!Sv-Fugz`Tnw^?o?QN>kIN)a>m6*1yT@$Q41QeS6jBUEAT4p}uU>yOW;!?(a@uBXKlvKd6a9)b_!xXpWF1 zMG@}Q1Rt24v|eFWle77_jA%tX9@^`1EjP_oguNc)kiHwtPPP8D6Rv7~N!!*=rCmcK zUs42g!&Tsa_RU*LR3;B?}i*Mv|C9egC4Y&#VmXSs(v%woR?rHa6&=G{iup zIZjZxvx5BJzeR_(TK$4%Y$Z|bUG$Xbk9ihste|s*0*^`RL;Ki~AS=S1nur2ykZX1{ zlPE;k-$|o^63;vqnf~}Py(dA67}B1ah$8{FhD&obze*wk zq-=Pbd?Y^6u|g}+QAh-&8B8=gxGiPYNx|=5_)Xi_erR`NcB1{9t$Uk>YI69Rq~@$nZ3wOip{H@Y{ z;f@&z)w~@PU@j3rBW_KFMuMYgWFi6S?V8EXBF??U+&wOy4ESN;tpNhl;QtQlIgvFt zeQ8}uo!MUBXVGqSsH}S|| zVNv|OXinjFAzcXKei@s93YFz4(oS_2YR1?Li2y>FfuyvJgF8&U^Nw#WBv-b1yw3S(|sz3a&KUCj+Rlw0Ba(5@%-me4e*6A}iu z>(g~~|5cOhbat2@81t)b`ozl~52mL1il$u;gjIR_U`fFqn31;y%nE|RtT3c1@`GX8 zjX=B!0!)&;V1CL*uuKjHCnBoYIAN>3_xNCMt0FtoAUYcu{Hw(%z{SmvHscc zCz~jplQtQ;VXJdTML3ihL_6OzjB$C0!2d@@tSQqvx;%H}K8p<9T^3O~n-(1I?>;T4 z&q9Nh9kqH*!E>^t51_rBT(d=o4&B=@K7Gr71M#xv2zpNf+FYFUSkFm~=GPgr1`*D+7~fG#ZOVVf_5BKg|Kn%P|J!~PmSM{dVQu;V_FQUsZaT3t_PsTG z?I!;;Q&Sru8nZU{V`>IeRomkY&FFihd0|McUYzm9)ri?Ia+mU z)m24Rr9Eq6K4!1g_}@-EA3>VYn;MWf5@pk!2Ho0pM0Lj3z9plHfjXEJ1dIC;b1Kq#ey`7v5d~0000C!9-gs*@?wOFPDc3TLC+gIi8qrnqX(Sd!oRW)p(~-x30?lARJ?Ie zR-~XRO(~nA?IgVzeK1Ygxg`!aO{r-yC+AyW{rAHHk8ShUnZcU#g#8mIo$W3M{s*}^ z=bv(XwxxGmoc{C^3U>ZK#X3PRA^qyry1C>jdBt9@OkwCzC$a>*cO_gWD!5YXVQys? zI;UY@ob~MPT=lDw@7Uw}YQ6O%iIp*p!{%67`^{hxo~ZA8yN?;)ZW;|AhIvE|E`a1Z zKTiz>+1`e0bjso#Eu1ajEzmIjHOQus(kGyr6F4_5wm1lk(Jr!B3oPgqC;hb~SFv34 zy-=z)%+LTC8hrROE{#1*XLA0E+X$O|DEO;j&5F*GmVP5$_>c|UU0D@A58g|;X5oM= zJzUbNxV^wFBH=ME2;kQlEBXE2oo#A)Y&z|Ija(vV8flM=ov0!LzF&N7t^5A{+<6P| zQoXTqiBPS&RVAUos2Nz>u#Y!TjjwV<8++8o$bDq&QTyZ|HZ#Cg!nNm7^`OLGwIc?T zRQJ|Yq{)Mm#V*2aBjtz(vOQAf^;T4z5|u>Z#a49nyK$FUWC;%?l6ijDGwS=EeQz<= zrm9--J;{s==`OucG%%x*ZT-Y+sDGGBnc_v8vXn-i@^|QJBMcco>^E>W;P-nsv`G+I zFdfz>Q%w|`bNN8Yf+x)zs_;e!B1{yOJW(TCF+rhkUphfJ@$4RZyv9EQEy+=0_uV>p z9}KG`%AkCrw2fUak=&P=fc1Y1<%z4Zfo;<`96Z88(nM%sqxx>Rtv-hWBy!oeq<%F~ zOC%svNnCO4lpPpBtCY@YDi2&Ferii*G3&YT;Hs3ZbZ~D}yl-ev*~a@tPia8XK)`Zx zW^{{hR;I!b?>4e5Re?BoQx9=6d7(y+ldAu!@IK4L;sW`uq zwNscE)>GiKl%$5t+lNm}+kT+FCdb2Ww$x+34^^r8yumV z>roP@WU3<8D6G)n;Kk&3b5e7Y-$qF1;TCZNgmzHq1@0CUZ*Y8pD0NXGd!vxu@AlI8xtZnrgnWhhZ5 zTDFta*4)w?&i@8*A8m|49VNW@VrHXSt^5_gl%gYKy7*V!!;27bhysXH>082Je#9jV zJ@=HC1v1AndyqYl!KJmTIWV;ve9}}IP_g%;zne+d$uc?fe_Dx8Y-41QL2p~0|A2ErBww&fQ3AeZ^T1nD}Z4=!mce zgNy#;t9=_*t3p4MqJufCku6m&on%$g$yn%d_N@~k;ten9>LI@RJMsj`yiQ=_cjItO z+ZLqk$LzNv24#4KYLm2$&9CXV%dbxlLYQyPiX<0U&NoT=Y8|v%^RWY0Btd^uz)qoW zF&ky#57t$hp09+pS%zo(sm|Zli0-sX6GZ!zbzB`fKW_MXkJy`>>hC}yE=n8f?1W#& z3SDLl`^v4X;Pjt;3+2k6Cj)V1IAMp;{|MFG;L5s|KN@&;x)k~{jk_b~?9hzp`YbOC{LS7Vs5Rv2R?m>`;w?%qde zzp`L7da=^QtO5WG_0P|r3`ieJeJ3Aiy<{nZg! z=NK9B*5H+O*Xvdan#wozFErRnh#*0YdOEZW&Y4DGUp}5cJm2Mb0q)-d){@L8HoSO@ z2Uv@vIPobmeesj%-xA^Hm%#pgI-|pAB4MsTK5xyF+CGdz&*bvoo*0M7@q1RtS_NhT zk^bZrb%EsnG7kL330TX3&W=?1`%_nlai5Rv9-5!JpnS(A#3pK%0T<82Y)2(j`2w10 znO?rDb|68<7ih03&(V4IU%^L9Hi@hJH}{=7m~_vWFx32CAXVuAR@eCZyE=qX9_~n)lDL?v>M;W1nYBXJczcSNV z3F~Hau#CQDYkAm+!I^S3r)y^_S%Qp33mDtvhx194XY;N5z%7I&g?yQ5!gDiY*O8A@ z6CS>6b1d3(5qCWd3{nEv+!1j;{i_g|xq3%e8ITR4K}I7sMst+5ZxbN=n2l3MJewk3 zD1AyNyBr!$Sx6lR>XMgNV#V-Fd`gMGDE|j;IEmUy1 z#^{jyzAo0^M#Dui#BVmKkzOgUHR=KkEN)5rEAl9FRNMy@_7ZU?F*R#WZvbXg&M%6D zXNHbjuikAnHe95e0vAm~%5@-P+^jP|X&pAQFuIVMR7|@Fo!moA<&RmIYH&yE3uXbdpqZI9vPB3eOyF|lRM%O>fKm> z*>ZzvZeQQnv&+;xB9-w)1PW4Bd{Mm}IJEJN6bT`-Rm{o$jh(26Z4(f~mPc`lmvO7&BOpcT35tZOTlP*ovz$L;hDACH@1>@A9))0+o#mPax3^ zL?gNz+4`_~lxpaMdbosmicZQb|{n(lcOgvtEYi**g_G!n z=}U-47^lVIh^3XXqtp0O$>mJmP=ip9e)Ly2!C;yXA8d%SQzp%sJx%X^k;alrr}TDw z<>4JL*2cgOr*?uMD(f5I(OMnz{gZ6ee$+8Du5&449OAVq3MY`BW9$G~4B;UapbmrB z_ZiME85r7u)at#4o@$}jaex) z~*)Y*U8 z*Bt4y&Mxeaiu?h~7E&CjGp8LBNwp+^C^_)ib@TfiCxNIqtQ~&E@uJzux48}o$ zg$R?7T|Gb*tCkw7R&ji;9I-zVRdbG?G1BF~rSOdE!_1I7KMCYrC4wsl@pP+Cem<2# z0}!8uM`GdzDy@bGjJ#&h!cl$b#*$inTnNLZyKCg*%>;dphY!p$LI+OFapHq!+#X}X zX`9?~7MMnt>|wkndTc|?D_D#$EZ!;tD1rbMjgD_z!-ZNS^;9g zo7xdxH(ba{RL&L9yHGL@I~xhQlDb3l*UEsguDC30mc78V{{1cS8F7qBM&4tPp#leW z$tcO*%=ensU<%OtPapcDeUdZdcgVQV0S~-l;&qZ#Migm=IOI-o(cle`ri!#pP!d=@ z`5SaqH79bAe0`br$Q?$d;^|@MtjfILco3PRVhQ6P#V+Rv?me~BLgz;Y2>ao2d*72qP37;UG)OlJ}~eeY*_rK-2{^ZH=H;=6_HeIx>wn z#Y_Rip}_JPRO4y7XC62Gk*%nu-m&9gOJ{Nurw!pnStxcnh^3L0C5}{GNRyo%7^R|% z&qfD&k;M(D8li3+Uj~J>$M*8EF{sZCSR3Gy6W0i*;U}0F+EIKN8|VbKhc z$+a;bE4r-vz08jNMTTa+`~iBaN2q6#*bTeSIT3FjhlOB1N9z? z^fHXdE#7dxYCHjKdX_01reoJ?5aHz|iWdgXBzQSLW}|-_vnEs**X(Skl+J}N%eV*# zrX}+jM>g8BFX}a=lj2RQx+^BI@r@AxGR(;flsJc-HIsa!Zyw7tXB1`p1W1{vibrU+ zB+B)`NI3`Hc0;G|iX9#8K1Go8!}me9$!3`2v2$p(%;{%SV>(7GDaZN$TBr}6AvWZ4 zN3AI^7;MAqw7yiZcl3?`*H_?Ze)sSNK1$D-8T_*3yQ?1AD3>RMpX#g%osO|8p>Ifo|4_^`qe_OELV z3IExR<)d_Zsfz)VRhDNi!envk=vcy^v`;ttpek-2afJQiP{5`p9GLhf`B z@%=J)H;}666wIdtv7^o5(?fkSNqiMcK&Jb5sRJ6}@>&1-Crf8^vE2#w~6|Ytaf_n`HXkbswj3vliS84d0q)oss z2eFfNC#8T6=+wg13wcrIg%x3S%CzzNCQDBNKoJ!C<_QeNibjwhV-je>-u+xEhTvcD zvJkRL=12l|T?lRdPAxhL@X-^Mf7Q;#nI=Y29@Wg>iHN&|w?TP03LN#5u+bIbG)QyR zp(gz@#98r{4FITzQnHhb&m0EoOmJ@ln)$U)(sq5X2}{%qNjX!aLm-q+ZY7BIlR#}| z^L!_k)C7!8LZGk`N;q$D413@t3()R~I$a8`7gkk}N>H5}dJfTGC9N;tsP4!N$=7*H zd}{fZOh`QaIIz4du$dAW4Ik+bVV&L@;Y8_Y$Aa|9aW1np!wW#P!Ft~l>BJZ-U@(AYuVIUx+m#MV*+;xq7+JTb>$B)87HeZ7ibX#63ZcUhTJ zB0QhcK$OqexC>%IOR3F!-{rVeV zd+aELPDM{jOieRsk%1G@^S@)J&2&TyD&L>iS1vvvd>?78*@QO{FAMKucA#i03jro> zhz~3q3o7MG*h9z6Gx z)f>8>ch+bKRty~=2g!`y2?OP4lSJzH!T3gqBVRm1!uTern0;~;16h(n*eR*0U`hDN z9M`>dze)MHiLlv9p+wYdM*ZAs32d*SvaB}F+_oy;3}0w$$-t1OY2i-uz{~%2L4*Es z(6=)QouA(azO|O4*aj3S=&tkcoy~->-eiFdzI#~8D}Bg?8Po2mnUL?`eXp{LQUUyg zvd$C-JW0@rL=->aQ%VQWjwW$%qbNI>CZ3#|8K*(y4t1i}*^S``@V#9rM`{ z@=ZBd3omRJvstHuAMkn)*eK>BWCkRkL~5qLBxL=GwDk_;MN^8SjxR=%BY$S?Hy)2= zTbuG}zsq}9ZHHIOLj|=(kNW8vW*zFbeP)ORs=V34?vP`KNBAe~A1j@Y9 zw;aNf@~)%ck${>FDsV5c2dtU3mo=`oImKvnTbLm7E96%_A=aM83z zkrg!o1-bax{ihv-&HB@$gy+?aL@Doz|GVdWJ1LCq+<|og(khqmIgw5qF*0N#l8vPR zkJ^G5m{DA(pZ{qG9t}W^gULRco8TvDVJ-p5`BPzU=Q)3bm}^u3R7Q5_@>X&7M(`DY z>8Vp9kLSSin}mS)sT~`D1q)!SBQ6V1iINAn&Xy{Q!Y>)`?CY?Wut-l$pNi5VG|N`R zK{jS!x`WM!f&#jtqbftf$D@F15d)QW!1W6Qx6BKzI7mMgiJMCUY(94Id4x7Jl(&swh(AaSA+LR~QI8WBYIxWi4hm6fsHa?`y8 za4f2gVcbf)@a5vZgiqouGV4N&BHsW`DmmFZ{9YpN31;ur&9+$%$p8iybB|^keS>vs zenC_1&-{2&F?d1uO`&jHf!RBT<39-kMP+eV38NH7<=gsk=nL9(?j(F3yETJK*Q&3D z!xmy?MDSd)g5kSD01(A9joJ8Wfuvs??b@g&46~?@qSN-}aTdQrQx`Ic*vb%>V1==b z1pjMtRLg4CZtNlb9?`JO7Z~00&No6){{yuP8;_*hoh4HacQI(Hto=d;ghd-n{=5l3 z1JzECD#bYWNEMaKv3b%Kp(8|AnF(T7g_I87j&>evPfI@wzHKe&I+3A5W)l-nb#_)3 zU4E+B{QK9Y{nOii{L{8!{Lj!d+lpsqL8A(Vx#BpwUN*i;$%1Ga_X-It)sY=CoJCDR z@`Ut?g@=bP!;^k8EaDkDrgn$O@6OSDVVy1*3Oxo>I!(9o?mN7~OCy7JI)X|w<9r>I z2}_`<2A`5&0pg7f90B`<{>d0^MSz@FAPl)W;sh$9{?w<+%A82pSanxP7xr}E1j%mP zo?oYZ{c#?A(#oW+?o~6(HLRN_OcIzvUfHg&Z_fT%?HiV1yF!E=9;RkReBu#`>@wpf z|0+iSn&89*$%^5q_e;qug(L6?~GdpmMu=UXpMdRjo4Wc8T*ne!hn z5n5}ZQSxi;-Eo;;l=xg`w^p~~Oy5}=n21j#j;~n9$fsTMyc>q&S|(0FGJ}B~lYGh_r`f^4wAju? z-J$XhXzj5dcaz@8y;_SNsTZZZ-ae%Q12C;T-WN{^SDs?jSASycL=R1~ukYme0s6=C zd8Zj=UvSHxdXOq)y??|piPYGfz6h3;b|EJLv@|h{{2Bn=)MuP(@$65E<-^&c4{;R> zSrz?8a((cn_5P31Z?&R-7yB`uwSz2&f5XCWR-TOPMWDpz_=g!x!rffb@g}%A9UTnT zthE_uSYp1UtzNANHTHN_Vjh-0_P?%M_1P1x?K*2N4Y+B3y(&%9+vexEbI5fqa_x;Z zF|sf?vW!Fc4!f^w7mR+hudFrd$TMm)wVjjmAxD_Ef$lOa2@q}^Xb*PHWQ-1cfr5R2 zMF>|QRhU;TD17R1($0t?+f`K~>B{=7EiT0*jhFzTCeR5z-A}#FKsKV&hL{;QbrnzS zl~C%hc(plBiJ_dQD|>QQ-IYZ{$C0qjqIQqJp|{QVYz<63SHoXL@!CHT&n&*@@&Bw- zb2y~*NQR#2@FpOnHnEeRbI?5%%y}{Pm!flPzpH|cGd-Y0;mKuf0Ex;`#=7`eHWzTL zVyL~Enqq_XtF#+0Q{Y0n@IhtW@}JT-=7*Kd=I51J=I6BUEbD`Fg?>dpSJPa?U(hYj z_j)z;WQT>xXEE8`=rE}+gvfh7+3Qm`6>-u@(xdFi2?cg8g>COJqW? zLR2qm?>{u8ggv`aKDiU!(i=z)@E@}t@W;>VYIuBiSF;gIduO6PQJV7b2dx(EiO0Z` zmzN8FR*s^67A)C^1c$g@>>SzMb3Jre(#ulO=#+md1ljw{Y5c>B>8Gt#stjFHXjCZs z=@+Z$?!AhGnTkv3X*%r2M)CXn?$^WH?w-T@v>}hHFuA+CcxH-<#J=ucnW9kntGF|& zz4u1ZG9j`hiK;&FVQK*x5fpnpX$g0FCE-89ZOVfAZnI9a;=H9Cq*8XF7s9^^-$ik;$F2}chtKl9d(jnWt8uNUOrJ|^*P%md4`9A>rM&7dk literal 0 HcmV?d00001 diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..b216f2d313cc673d8b8c4da591c174ebed52795c GIT binary patch literal 11873 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 literal 0 HcmV?d00001 diff --git a/composeApp/src/androidMain/res/values/strings.xml b/composeApp/src/androidMain/res/values/strings.xml new file mode 100644 index 0000000..b6c105f --- /dev/null +++ b/composeApp/src/androidMain/res/values/strings.xml @@ -0,0 +1,3 @@ + + Rick and Morty + \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/App.kt b/composeApp/src/commonMain/kotlin/App.kt new file mode 100644 index 0000000..01bd01d --- /dev/null +++ b/composeApp/src/commonMain/kotlin/App.kt @@ -0,0 +1,95 @@ +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import dev.icerock.moko.mvvm.compose.getViewModel +import dev.icerock.moko.mvvm.compose.viewModelFactory +import episode.data.EpisodeRemoteDataSource +import episode.data.EpisodeRepositoryImpl +import episode.presentation.EpisodeScreen +import episode.presentation.EpisodeViewModel +import episodes.data.EpisodesRemoteDataSource +import episodes.data.EpisodesRepositoryImpl +import episodes.presentation.EpisodesScreen +import episodes.presentation.EpisodesViewModel +import moe.tlaster.precompose.PreComposeApp +import moe.tlaster.precompose.navigation.NavHost +import moe.tlaster.precompose.navigation.rememberNavigator +import moe.tlaster.precompose.navigation.transition.NavTransition +import theme.Theme + +@Composable +fun App(darkTheme: Boolean) { + PreComposeApp { + Theme(darkTheme = darkTheme) { + // A surface container using the 'background' color from the theme + Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { + val navigator = rememberNavigator() + + NavHost( + navigator = navigator, + navTransition = NavTransition(), + initialRoute = NavRoute.EpisodesScreen.route, + ) { + scene( + route = NavRoute.EpisodesScreen.route, + navTransition = NavTransition(), + ) { + val episodesViewModel = + getViewModel( + key = Unit, + factory = viewModelFactory { + EpisodesViewModel( + repository = EpisodesRepositoryImpl(remote = EpisodesRemoteDataSource()), + ) + }, + ) + val uiState by episodesViewModel.uiState.collectAsState() + LaunchedEffect(episodesViewModel) { + episodesViewModel.updateEpisodes() + } + + EpisodesScreen( + uiState = uiState, + modifier = Modifier.fillMaxSize(), + onEpisodeClicked = { + navigator.navigate(route = NavRoute.EpisodeScreen.route) + }, + ) + } + scene( + route = NavRoute.EpisodeScreen.route, + navTransition = NavTransition(), + ) { + val episodeViewModel = + getViewModel( + key = Unit, + factory = viewModelFactory { + EpisodeViewModel( + episodeId = 1, + repository = EpisodeRepositoryImpl(remote = EpisodeRemoteDataSource()), + ) + }, + ) + val uiState by episodeViewModel.uiState.collectAsState() + LaunchedEffect(episodeViewModel) { + episodeViewModel.updateEpisode() + } + + EpisodeScreen( + uiState = uiState, + modifier = Modifier.fillMaxSize(), + onCharacterClicked = { + navigator.navigate(route = NavRoute.CharacterScreen.route) + }, + ) + } + } + } + } + } +} diff --git a/composeApp/src/commonMain/kotlin/Greeting.kt b/composeApp/src/commonMain/kotlin/Greeting.kt new file mode 100644 index 0000000..887d835 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/Greeting.kt @@ -0,0 +1,7 @@ +class Greeting { + private val platform = getPlatform() + + fun greet(): String { + return "Hello, ${platform.name}!" + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/NavRoute.kt b/composeApp/src/commonMain/kotlin/NavRoute.kt new file mode 100644 index 0000000..311bd42 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/NavRoute.kt @@ -0,0 +1,8 @@ +sealed class NavRoute(val route: String) { + + data object EpisodesScreen : NavRoute(route = "/episodes_screen") + + data object EpisodeScreen : NavRoute(route = "/episode_screen") + + data object CharacterScreen : NavRoute(route = "/character_screen") +} diff --git a/composeApp/src/commonMain/kotlin/Platform.kt b/composeApp/src/commonMain/kotlin/Platform.kt new file mode 100644 index 0000000..87ca3ff --- /dev/null +++ b/composeApp/src/commonMain/kotlin/Platform.kt @@ -0,0 +1,5 @@ +interface Platform { + val name: String +} + +expect fun getPlatform(): Platform \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/episode/data/EpisodeRemoteDataSource.kt b/composeApp/src/commonMain/kotlin/episode/data/EpisodeRemoteDataSource.kt new file mode 100644 index 0000000..c2d1d46 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/EpisodeRemoteDataSource.kt @@ -0,0 +1,32 @@ +package episode.data + +import episode.data.model.CharacterResponse +import episode.data.model.EpisodeResponse +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.get +import io.ktor.serialization.kotlinx.json.json + +class EpisodeRemoteDataSource { + + private val httpClient = HttpClient { + install(ContentNegotiation) { + json() + } + } + + suspend fun fetchEpisode(episodeId: Int): EpisodeResponse = + httpClient + .get("https://rickandmortyapi.com/api/episode/$episodeId") + .body() + + suspend fun fetchCharacters(characterIds: List): List = + httpClient + .get("https://rickandmortyapi.com/api/character/${characterIds.joinToString(",")}") + .body>() + + fun close() { + httpClient.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/episode/data/EpisodeRepositoryImpl.kt b/composeApp/src/commonMain/kotlin/episode/data/EpisodeRepositoryImpl.kt new file mode 100644 index 0000000..a4d8094 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/EpisodeRepositoryImpl.kt @@ -0,0 +1,51 @@ +package episode.data + +import episode.data.model.CharacterResponse +import episode.data.model.EpisodeResponse +import episode.domain.EpisodeRepository +import episode.domain.model.Character +import episode.domain.model.Episode + +internal class EpisodeRepositoryImpl( + private val remote: EpisodeRemoteDataSource, +) : EpisodeRepository { + + override suspend fun getEpisode(episodeId: Int): Episode { + val episodeResponse = remote.fetchEpisode(episodeId) + val characterIds: List = episodeResponse.characters.map { characterUrl -> + characterUrl.substringAfterLast("/").toInt() + } + val characters = remote.fetchCharacters(characterIds).map { characterResponse -> + characterResponse.toCharacter() + } + + return episodeResponse.toEpisode(characters) + } + + private fun EpisodeResponse.toEpisode(characters: List): Episode { + return Episode( + id = id, + name = name, + episode = episode, + characters = characters, + ) + + } + + private fun CharacterResponse.toCharacter() = Character( + id = id, + name = name, + status = status, + species = species, + type = type, + gender = gender, + origin = origin.name, + location = location.name, + image = image, + created = created, + ) + + override fun close() { + remote.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponse.kt b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponse.kt new file mode 100644 index 0000000..6ac39f4 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponse.kt @@ -0,0 +1,33 @@ +package episode.data.model + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CharacterResponse( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("status") + val status: String, + @SerialName("species") + val species: String, + @SerialName("type") + val type: String, + @SerialName("gender") + val gender: String, + @SerialName("origin") + val origin: CharacterResponseOrigin, + @SerialName("location") + val location: CharacterResponseLocation, + @SerialName("image") + val image: String, + @SerialName("episode") + val episode: List, + @SerialName("url") + val url: String, + @SerialName("created") + val created: String, +) diff --git a/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseLocation.kt b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseLocation.kt new file mode 100644 index 0000000..2ad66c3 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseLocation.kt @@ -0,0 +1,13 @@ +package episode.data.model + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CharacterResponseLocation( + @SerialName("name") + val name: String, + @SerialName("url") + val url: String +) diff --git a/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseOrigin.kt b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseOrigin.kt new file mode 100644 index 0000000..cb2b92b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/model/CharacterResponseOrigin.kt @@ -0,0 +1,13 @@ +package episode.data.model + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CharacterResponseOrigin( + @SerialName("name") + val name: String, + @SerialName("url") + val url: String +) diff --git a/composeApp/src/commonMain/kotlin/episode/data/model/EpisodeResponse.kt b/composeApp/src/commonMain/kotlin/episode/data/model/EpisodeResponse.kt new file mode 100644 index 0000000..999655c --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/data/model/EpisodeResponse.kt @@ -0,0 +1,23 @@ +package episode.data.model + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EpisodeResponse( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("air_date") + val airDate: String, + @SerialName("episode") + val episode: String, + @SerialName("characters") + val characters: List, + @SerialName("url") + val url: String, + @SerialName("created") + val created: String, +) diff --git a/composeApp/src/commonMain/kotlin/episode/domain/EpisodeRepository.kt b/composeApp/src/commonMain/kotlin/episode/domain/EpisodeRepository.kt new file mode 100644 index 0000000..158ee8b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/domain/EpisodeRepository.kt @@ -0,0 +1,8 @@ +package episode.domain + +import episode.domain.model.Episode + +interface EpisodeRepository { + suspend fun getEpisode(episodeId: Int): Episode + fun close() +} diff --git a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterDetails.kt b/composeApp/src/commonMain/kotlin/episode/domain/model/Character.kt similarity index 57% rename from app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterDetails.kt rename to composeApp/src/commonMain/kotlin/episode/domain/model/Character.kt index 6698cea..c77858c 100644 --- a/app/src/main/kotlin/com/mohsenoid/rickandmorty/view/model/ViewCharacterDetails.kt +++ b/composeApp/src/commonMain/kotlin/episode/domain/model/Character.kt @@ -1,14 +1,14 @@ -package com.mohsenoid.rickandmorty.view.model - -data class ViewCharacterDetails( - val id: Int, - val name: String, - val status: String, - val species: String, - val gender: String, - val origin: String, - val location: String, - val imageUrl: String, - val created: String, - val isKilledByUser: Boolean, -) +package episode.domain.model + +data class Character( + val id: Int, + val name: String, + val status: String, + val species: String, + val type: String, + val gender: String, + val origin: String, + val location: String, + val image: String, + val created: String, +) diff --git a/composeApp/src/commonMain/kotlin/episode/domain/model/Episode.kt b/composeApp/src/commonMain/kotlin/episode/domain/model/Episode.kt new file mode 100644 index 0000000..6eb0163 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/domain/model/Episode.kt @@ -0,0 +1,8 @@ +package episode.domain.model + +data class Episode( + val id: Int, + val name: String, + val episode: String, + val characters: List, +) diff --git a/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeScreen.kt b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeScreen.kt new file mode 100644 index 0000000..7165bdd --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeScreen.kt @@ -0,0 +1,95 @@ +package episode.presentation + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import episode.domain.model.Character +import io.kamel.image.KamelImage +import io.kamel.image.asyncPainterResource +import io.ktor.http.Url + +@Composable +fun EpisodeScreen( + uiState: EpisodeUiState, + modifier: Modifier = Modifier, + onCharacterClicked: (characterId: Int) -> Unit, +) { + Column(modifier = modifier) { + when (uiState) { + EpisodeUiState.Loading -> { + AnimatedVisibility(visible = true) { + Text(text = "Loading...", style = MaterialTheme.typography.titleLarge) + } + } + + is EpisodeUiState.Success -> { + AnimatedVisibility(visible = true) { + LazyColumn( + modifier = Modifier.fillMaxWidth().padding(16.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + items(uiState.episode.characters) { character -> + CharacterItem( + character = character, + onCharacterClicked = onCharacterClicked, + ) + } + } + } + } + + is EpisodeUiState.Error -> { + AnimatedVisibility(visible = true) { + Text( + text = "Error: ${uiState.message}", + style = MaterialTheme.typography.titleLarge, + ) + } + } + } + } +} + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun CharacterItem( + character: Character, + modifier: Modifier = Modifier, + onCharacterClicked: (characterId: Int) -> Unit, +) { + Card( + onClick = { onCharacterClicked(character.id) }, + modifier = modifier + .padding(8.dp) + .fillMaxWidth(), + elevation = CardDefaults.cardElevation(defaultElevation = 1.dp), + ) { + Column( + modifier = Modifier + .padding(8.dp) + .fillMaxWidth(), + ) { + KamelImage( + resource = asyncPainterResource(data = Url(character.image)), + modifier = Modifier.fillMaxWidth(), + contentDescription = character.name, + ) + Text(text = character.name, style = MaterialTheme.typography.titleSmall) + Text(text = character.created, style = MaterialTheme.typography.titleLarge) + Text(text = character.status, style = MaterialTheme.typography.titleMedium) + } + } +} diff --git a/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeUiState.kt b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeUiState.kt new file mode 100644 index 0000000..7838b7e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeUiState.kt @@ -0,0 +1,9 @@ +package episode.presentation + +import episode.domain.model.Episode + +sealed interface EpisodeUiState { + data object Loading : EpisodeUiState + data class Success(val episode: Episode) : EpisodeUiState + data class Error(val message: String) : EpisodeUiState +} diff --git a/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeViewModel.kt b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeViewModel.kt new file mode 100644 index 0000000..6cc97af --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episode/presentation/EpisodeViewModel.kt @@ -0,0 +1,28 @@ +package episode.presentation + +import dev.icerock.moko.mvvm.viewmodel.ViewModel +import episode.domain.EpisodeRepository +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class EpisodeViewModel( + private val episodeId: Int, + private val repository: EpisodeRepository, +) : ViewModel() { + + private val _uiState: MutableStateFlow = MutableStateFlow(EpisodeUiState.Loading) + val uiState: StateFlow by ::_uiState + + fun updateEpisode() { + viewModelScope.launch { + val episode = repository.getEpisode(episodeId) + _uiState.value = EpisodeUiState.Success(episode) + } + } + + override fun onCleared() { + super.onCleared() + repository.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRemoteDataSource.kt b/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRemoteDataSource.kt new file mode 100644 index 0000000..19102fa --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRemoteDataSource.kt @@ -0,0 +1,29 @@ +package episodes.data + +import episodes.data.model.EpisodesResponse +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.get +import io.ktor.client.request.parameter +import io.ktor.serialization.kotlinx.json.json + +class EpisodesRemoteDataSource { + + private val httpClient = HttpClient { + install(ContentNegotiation) { + json() + } + } + + suspend fun fetchEpisodes(page: Int): EpisodesResponse = + httpClient + .get("https://rickandmortyapi.com/api/episode") { + parameter("page", page) + } + .body() + + fun close() { + httpClient.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRepositoryImpl.kt b/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRepositoryImpl.kt new file mode 100644 index 0000000..41f9d25 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/data/EpisodesRepositoryImpl.kt @@ -0,0 +1,26 @@ +package episodes.data + +import episodes.domain.model.Episode +import episodes.domain.EpisodesRepository + +internal class EpisodesRepositoryImpl( + private val remote: EpisodesRemoteDataSource, +) : EpisodesRepository { + + override suspend fun getEpisodes(page: Int): List { + return remote.fetchEpisodes(page).episodesResponseResults.map { + Episode( + id = it.id, + name = it.name, + airDate = it.airDate, + episode = it.episode, + characters = it.characters, + created = it.created, + ) + } + } + + override fun close() { + remote.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponse.kt b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponse.kt new file mode 100644 index 0000000..64a8952 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponse.kt @@ -0,0 +1,12 @@ +package episodes.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EpisodesResponse( + @SerialName("info") + val episodesResponseInfo: EpisodesResponseInfo, + @SerialName("results") + val episodesResponseResults: List +) diff --git a/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseInfo.kt b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseInfo.kt new file mode 100644 index 0000000..348f213 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseInfo.kt @@ -0,0 +1,16 @@ +package episodes.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EpisodesResponseInfo( + @SerialName("count") + val count: Int, + @SerialName("pages") + val pages: Int, + @SerialName("next") + val next: String, + @SerialName("prev") + val prev: String? +) diff --git a/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseResult.kt b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseResult.kt new file mode 100644 index 0000000..a7fe6a7 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/data/model/EpisodesResponseResult.kt @@ -0,0 +1,22 @@ +package episodes.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EpisodesResponseResult( + @SerialName("id") + val id: Int, + @SerialName("name") + val name: String, + @SerialName("air_date") + val airDate: String, + @SerialName("episode") + val episode: String, + @SerialName("characters") + val characters: List, + @SerialName("url") + val url: String, + @SerialName("created") + val created: String, +) diff --git a/composeApp/src/commonMain/kotlin/episodes/domain/EpisodesRepository.kt b/composeApp/src/commonMain/kotlin/episodes/domain/EpisodesRepository.kt new file mode 100644 index 0000000..5ca5f6e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/domain/EpisodesRepository.kt @@ -0,0 +1,8 @@ +package episodes.domain + +import episodes.domain.model.Episode + +interface EpisodesRepository { + suspend fun getEpisodes(page: Int): List + fun close() +} diff --git a/composeApp/src/commonMain/kotlin/episodes/domain/model/Episode.kt b/composeApp/src/commonMain/kotlin/episodes/domain/model/Episode.kt new file mode 100644 index 0000000..e487a31 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/domain/model/Episode.kt @@ -0,0 +1,10 @@ +package episodes.domain.model + +data class Episode( + val id: Int, + val name: String, + val airDate: String, + val episode: String, + val characters: List, + val created: String +) diff --git a/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesScreen.kt b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesScreen.kt new file mode 100644 index 0000000..9167f3e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesScreen.kt @@ -0,0 +1,87 @@ +package episodes.presentation + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import episodes.domain.model.Episode + +@Composable +fun EpisodesScreen( + uiState: EpisodesUiState, + modifier: Modifier = Modifier, + onEpisodeClicked: (episodeId: Int) -> Unit, +) { + Column(modifier = modifier) { + when (uiState) { + EpisodesUiState.Loading -> { + AnimatedVisibility(visible = true) { + Text(text = "Loading...", style = MaterialTheme.typography.titleLarge) + } + } + + is EpisodesUiState.Success -> { + AnimatedVisibility(visible = uiState.episodes.isNotEmpty()) { + LazyColumn( + modifier = Modifier.fillMaxWidth().padding(16.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + items(uiState.episodes) { episode -> + EpisodeItem( + episode = episode, + onEpisodeClicked = onEpisodeClicked, + ) + } + } + } + } + + is EpisodesUiState.Error -> { + AnimatedVisibility(visible = true) { + Text( + text = "Error: ${uiState.message}", + style = MaterialTheme.typography.titleLarge, + ) + } + } + } + } +} + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun EpisodeItem( + episode: Episode, + modifier: Modifier = Modifier, + onEpisodeClicked: (episodeId: Int) -> Unit, +) { + Card( + onClick = { onEpisodeClicked(episode.id) }, + modifier = modifier + .padding(8.dp) + .fillMaxWidth(), + elevation = CardDefaults.cardElevation(defaultElevation = 1.dp), + ) { + Column( + modifier = Modifier + .padding(8.dp) + .fillMaxWidth(), + ) { + Text(text = episode.episode, style = MaterialTheme.typography.titleSmall) + Text(text = episode.name, style = MaterialTheme.typography.titleLarge) + Text(text = episode.airDate, style = MaterialTheme.typography.titleMedium) + } + } +} diff --git a/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesUiState.kt b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesUiState.kt new file mode 100644 index 0000000..77212f5 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesUiState.kt @@ -0,0 +1,9 @@ +package episodes.presentation + +import episodes.domain.model.Episode + +sealed interface EpisodesUiState { + data object Loading : EpisodesUiState + data class Success(val episodes: List) : EpisodesUiState + data class Error(val message: String) : EpisodesUiState +} diff --git a/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesViewModel.kt b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesViewModel.kt new file mode 100644 index 0000000..644a307 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/episodes/presentation/EpisodesViewModel.kt @@ -0,0 +1,25 @@ +package episodes.presentation + +import dev.icerock.moko.mvvm.viewmodel.ViewModel +import episodes.domain.EpisodesRepository +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class EpisodesViewModel(private val repository: EpisodesRepository) : ViewModel() { + + private val _uiState: MutableStateFlow = MutableStateFlow(EpisodesUiState.Loading) + val uiState: StateFlow by ::_uiState + + fun updateEpisodes() { + viewModelScope.launch { + val episodes = repository.getEpisodes(1) + _uiState.value = EpisodesUiState.Success(episodes) + } + } + + override fun onCleared() { + super.onCleared() + repository.close() + } +} diff --git a/composeApp/src/commonMain/kotlin/theme/Color.kt b/composeApp/src/commonMain/kotlin/theme/Color.kt new file mode 100644 index 0000000..6f67295 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/theme/Color.kt @@ -0,0 +1,10 @@ +@file:Suppress("MagicNumber") + +package theme + +import androidx.compose.ui.graphics.Color + +val colorPrimary = Color(0xFF008577) +val colorTertiary = Color(0xFF00574B) +val colorSecondary = Color(0xFFD81B60) +val colorSurface = Color(0xFF424242) \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/theme/Theme.kt b/composeApp/src/commonMain/kotlin/theme/Theme.kt new file mode 100644 index 0000000..3347fe6 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/theme/Theme.kt @@ -0,0 +1,47 @@ +package theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable + +private val DarkColorScheme = darkColorScheme( + primary = colorPrimary, + secondary = colorSecondary, + tertiary = colorTertiary, + surface = colorSurface, +) + +private val LightColorScheme = lightColorScheme( + primary = colorPrimary, + secondary = colorSecondary, + tertiary = colorTertiary + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun Theme( + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit, +) { + val colorScheme = when { + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/theme/Type.kt b/composeApp/src/commonMain/kotlin/theme/Type.kt new file mode 100644 index 0000000..1ab1b36 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/theme/Type.kt @@ -0,0 +1,34 @@ +package theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/composeApp/src/commonMain/resources/compose-multiplatform.xml b/composeApp/src/commonMain/resources/compose-multiplatform.xml new file mode 100644 index 0000000..d7bf795 --- /dev/null +++ b/composeApp/src/commonMain/resources/compose-multiplatform.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/composeApp/src/desktopMain/kotlin/Platform.jvm.kt b/composeApp/src/desktopMain/kotlin/Platform.jvm.kt new file mode 100644 index 0000000..f5e7e49 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/Platform.jvm.kt @@ -0,0 +1,5 @@ +class JVMPlatform: Platform { + override val name: String = "Java ${System.getProperty("java.version")}" +} + +actual fun getPlatform(): Platform = JVMPlatform() \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/main.kt b/composeApp/src/desktopMain/kotlin/main.kt new file mode 100644 index 0000000..8f82e67 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/main.kt @@ -0,0 +1,16 @@ +import androidx.compose.desktop.ui.tooling.preview.Preview +import androidx.compose.runtime.Composable +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application + +fun main() = application { + Window(onCloseRequest = ::exitApplication) { + App() + } +} + +@Preview +@Composable +fun AppDesktopPreview() { + App() +} \ No newline at end of file diff --git a/composeApp/src/iosMain/kotlin/MainViewController.kt b/composeApp/src/iosMain/kotlin/MainViewController.kt new file mode 100644 index 0000000..1572b73 --- /dev/null +++ b/composeApp/src/iosMain/kotlin/MainViewController.kt @@ -0,0 +1,3 @@ +import androidx.compose.ui.window.ComposeUIViewController + +fun MainViewController() = ComposeUIViewController { App(darkTheme = true) } diff --git a/composeApp/src/iosMain/kotlin/Platform.ios.kt b/composeApp/src/iosMain/kotlin/Platform.ios.kt new file mode 100644 index 0000000..5cef987 --- /dev/null +++ b/composeApp/src/iosMain/kotlin/Platform.ios.kt @@ -0,0 +1,7 @@ +import platform.UIKit.UIDevice + +class IOSPlatform: Platform { + override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion +} + +actual fun getPlatform(): Platform = IOSPlatform() \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index aa522a6..9e52644 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,19 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn +kotlin.code.style=official + +#Gradle +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" + + +#Compose +org.jetbrains.compose.experimental.uikit.enabled=true + +#Android android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true -# DataNetworkModule.kt: (22, 2): This class can only be used with the compiler argument '-Xopt-in=kotlin.RequiresOptIn' --Xopt-in=kotlin.RequiresOptIn +android.nonTransitiveRClass=true + +#MPP +kotlin.mpp.androidSourceSetLayoutVersion=2 +kotlin.mpp.enableCInteropCommonization=true + +#Development +development=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..a73d757 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,57 @@ +[versions] +compose = "1.5.4" +compose-plugin = "1.5.11" +compose-compiler = "1.5.5" +agp = "8.1.4" +android-minSdk = "24" +android-compileSdk = "34" +android-targetSdk = "34" +androidx-activityCompose = "1.8.1" +androidx-core-ktx = "1.12.0" +androidx-appcompat = "1.6.1" +androidx-material = "1.10.0" +androidx-navigation-compose = "2.7.5" +androidx-constraintlayout = "2.1.4" +androidx-test-junit = "1.1.5" +androidx-espresso-core = "3.5.1" +kotlin = "1.9.21" +kotlinx-couroutines = "1.7.3" +junit = "4.13.2" +ktor = "2.3.6" +moko-mvvm = "0.16.1" +kamel = "0.8.3" +precompose = "1.5.8" + +[libraries] +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } +compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } +compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core-ktx" } +androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-junit" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-espresso-core" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } +androidx-material3 = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidx-navigation-compose" } +androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" } +androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } +ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } +moko-mvvm-core = { module = "dev.icerock.moko:mvvm-core", version.ref = "moko-mvvm" } +moko-mvvm-compose = { module = "dev.icerock.moko:mvvm-compose", version.ref = "moko-mvvm" } +kamel = { module = "media.kamel:kamel-image", version.ref = "kamel" } +precompose = { module = "moe.tlaster:precompose", version.ref = "precompose" } + +[plugins] +jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } +androidApplication = { id = "com.android.application", version.ref = "agp" } +androidLibrary = { id = "com.android.library", version.ref = "agp" } +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlinXSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 43784 zcmZs?V{~Rwvn?Fkwrv}oj&0kv`NZkiwrxGJZ6_V8V;h}(ea=1Oz4wgq{n%sG*sJ#5 zf2!7;yQ=2UEO`74IHZy+I0QzrvO8uX9y%ySa?mnvqNLV8{0DVViJKuj_{N|8_y>I+MxT2rn3@Q#>wn~1E zL?7Lobaaai$f~PJ0h}NW%Jz=o9G(v`1G-hf3`!4Hykd#lU+;7v>s6JhQ7>+NykDU( z+Yh)P+pD#Xf_Ezp%e``u9= zPJL0(x6YXP{nVHO6?>|5I(OEX+z0Fdei~>3M`J^9Le#>-%*cHO2dI9HaE61$a74)& zhG`72UvRy2>GhSbe7%JS*{^BAj@7^R_`#yP-hcCvM0hriNtFRwQ8sdle)1Ez%QcHa$>LXwe6Dl*#&-bzELzYX(EA*tDQjPTN z_Iy$>1z$iZhRJU_kP-6fwFoL`ATuxgebp735D2?M!BWyU#RUSYV9ge!Wt(Ryg2c# zE!mNwc?3zLL{3iQ6)y8~c~s=m4Xqg@K3wMbk>I?_-Uz?T$HzrkC9iM}Pe>ON*;6DX zAAhT%>H<2)Tbb?04j7l5tjnh^NK&u3&|8|x9FUM@&C|WbNe>8;>Zst)1WXai?2}(@ zyKj-PO(w)jgcXLvm(rNz(X6t9Y6OW>TfRtL8F0CuNP|)h%mfKHTyb}1*+arFxFC1U z(N0B0N3Jcz26y6Ul(ROd=0s+E8`mO|%&tmuVsXf&%C< zqfuZ+k9Lczb4Li|3N*~kFWFblf~n^$3YVNq6NL&>E`&s_PXoyxkILoa7=DUIu3pa^ zbjt28Iln9>aXD?uYDI=>%f%@nd!*sacDx%hqN>9K2$r2N)@*sA+415I5pr2{acy3O z0sue0u{}YluJrg2MMai%uCnAS|1>N{x) z9W0h;+;^Q;m5Y1Pds=9%6L2UE$|ziEl`q?2-MJyt_O1MjCN!fwl1)PARjh-GPK-Bu ziBk^EHui_QP^405zFUzBY86#gXxXo~tO_j7sEQS_To{@n19bS|pHyoI$71br)Bq_% zKI<_wiEE{M!;;7m75H6Py81{;GMa{JeMKsHeh#zwafm})ycBUB89KUwLH+8iM(-enyqKq)oHH3hDjL8_*Fweo|@|9cT%{f zO-v5t@vOg5-KrPTr2t#GYJ)8@zQ@<478@tOj3h9r#~9`^Q#5+^aL}Wv7*J`&+|Vx@ z)BRL(#kD~Mwr_&pUDQs^fLcl~6?LZC$n&r)&u_?6eu_~zyQ*6+FP*qf$#iHG z2YPE|ZZ@No$<*C$7mSO|AFFFO$1DJum^n0}UN;9_VcV$ZMmrK0={c8_%D=nHmaMXi zLn410cRCiWs7{vSsL)&F+tZG2uyQKop$)mm`wetpa|?aR02T6+0J}-$e5Tw~i$ci59}-vZrgrm4909wfTB||ALOyJi_vsmyzG1%`*ElF%_(8r&emW?qs1{D6NY1hdkN6 z07ItKp8bQ!olQMB3Sen0Jy&kX17H59sC?9IOo92e=7EBncWnkSS&@h??=N|%=F1hG zSGJ+o9GvdE<*GX#`6P4GIp->PzJbw*4h;0=NT7%~D)9MW>0b$q#fS zPQU+~T!DiVv3L&u&UQ{7s>gh_Y{*s{)!Z3MmJJ5VyQyVm4*h!+mLYlbxHc7^s-Z|7u?n}w zt~M(a2Sx*m2>=rstd3iQH+HVUSiz-O6tq{s70C%sK{WQ;xh7kT+&hBZD(hK{7|Y4N z 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�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 Qc)^b}ObCdTt-n6~KSqm+J^%m! delta 39466 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 Ar2qf` diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 29e4134..3fa8f86 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0..fcb6fca 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,98 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 107acd3..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/iosApp/Configuration/Config.xcconfig b/iosApp/Configuration/Config.xcconfig new file mode 100644 index 0000000..7b7d0b8 --- /dev/null +++ b/iosApp/Configuration/Config.xcconfig @@ -0,0 +1,3 @@ +TEAM_ID= +BUNDLE_ID=com.mohsenoid.rickandmorty.RickandMorty +APP_NAME=Rick and Morty \ No newline at end of file diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9d88490 --- /dev/null +++ b/iosApp/iosApp.xcodeproj/project.pbxproj @@ -0,0 +1,408 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; + 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; + 7555FF7B242A565900829871 /* .app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = .app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 058557D7273AAEEB004C7B11 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 42799AB246E5F90AF97AA0EF /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; + 734E0479B5BED29E27C27622 /* xcuserdata */ = { + isa = PBXGroup; + children = ( + 734E0628ABD2E3465859F65E /* mohsenoid.xcuserdatad */, + ); + name = xcuserdata; + path = iosApp.xcodeproj/xcuserdata; + sourceTree = ""; + }; + 734E0628ABD2E3465859F65E /* mohsenoid.xcuserdatad */ = { + isa = PBXGroup; + children = ( + 734E0F4C8C678DC04422D63E /* xcschemes */, + ); + path = mohsenoid.xcuserdatad; + sourceTree = ""; + }; + 734E0F4C8C678DC04422D63E /* xcschemes */ = { + isa = PBXGroup; + children = ( + ); + path = xcschemes; + sourceTree = ""; + }; + 7555FF72242A565900829871 = { + isa = PBXGroup; + children = ( + AB1DB47929225F7C00F7AF9C /* Configuration */, + 7555FF7D242A565900829871 /* iosApp */, + 7555FF7C242A565900829871 /* Products */, + 42799AB246E5F90AF97AA0EF /* Frameworks */, + 734E0479B5BED29E27C27622 /* xcuserdata */, + ); + sourceTree = ""; + }; + 7555FF7C242A565900829871 /* Products */ = { + isa = PBXGroup; + children = ( + 7555FF7B242A565900829871 /* .app */, + ); + name = Products; + sourceTree = ""; + }; + 7555FF7D242A565900829871 /* iosApp */ = { + isa = PBXGroup; + children = ( + 058557BA273AAA24004C7B11 /* Assets.xcassets */, + 7555FF82242A565900829871 /* ContentView.swift */, + 7555FF8C242A565B00829871 /* Info.plist */, + 2152FB032600AC8F00CF470E /* iOSApp.swift */, + 058557D7273AAEEB004C7B11 /* Preview Content */, + ); + path = iosApp; + sourceTree = ""; + }; + AB1DB47929225F7C00F7AF9C /* Configuration */ = { + isa = PBXGroup; + children = ( + AB3632DC29227652001CCB65 /* Config.xcconfig */, + ); + path = Configuration; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7555FF7A242A565900829871 /* iosApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; + buildPhases = ( + F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */, + 7555FF77242A565900829871 /* Sources */, + 7555FF79242A565900829871 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iosApp; + productName = iosApp; + productReference = 7555FF7B242A565900829871 /* .app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7555FF73242A565900829871 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1130; + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = orgName; + TargetAttributes = { + 7555FF7A242A565900829871 = { + CreatedOnToolsVersion = 11.3.1; + }; + }; + }; + buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7555FF72242A565900829871; + productRefGroup = 7555FF7C242A565900829871 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7555FF7A242A565900829871 /* iosApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7555FF79242A565900829871 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Compile Kotlin Framework"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7555FF77242A565900829871 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, + 7555FF83242A565900829871 /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7555FFA3242A565B00829871 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7555FFA4242A565B00829871 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7555FFA6242A565B00829871 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; + DEVELOPMENT_TEAM = "${TEAM_ID}"; + ENABLE_PREVIEWS = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + ); + INFOPLIST_FILE = iosApp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + composeApp, + ); + PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; + PRODUCT_NAME = "${APP_NAME}"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7555FFA7242A565B00829871 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; + DEVELOPMENT_TEAM = "${TEAM_ID}"; + ENABLE_PREVIEWS = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", + ); + INFOPLIST_FILE = iosApp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + composeApp, + ); + PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; + PRODUCT_NAME = "${APP_NAME}"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7555FFA3242A565B00829871 /* Debug */, + 7555FFA4242A565B00829871 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7555FFA6242A565B00829871 /* Debug */, + 7555FFA7242A565B00829871 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7555FF73242A565900829871 /* Project object */; +} diff --git a/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/iosApp.xcscheme b/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/iosApp.xcscheme new file mode 100644 index 0000000..921065c --- /dev/null +++ b/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/iosApp.xcscheme @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/xcschememanagement.plist b/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..fa59f97 --- /dev/null +++ b/iosApp/iosApp.xcodeproj/xcuserdata/mohsenoid.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + iosApp.xcscheme + + orderHint + 0 + + + + diff --git a/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..ee7e3ca --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..8edf56e --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "app-icon-1024.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..53fc536fb9ac5c1dbb27c7e1da13db3760070a11 GIT binary patch literal 67285 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 BXNCX( literal 0 HcmV?d00001 diff --git a/iosApp/iosApp/Assets.xcassets/Contents.json b/iosApp/iosApp/Assets.xcassets/Contents.json new file mode 100644 index 0000000..4aa7c53 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/iosApp/iosApp/ContentView.swift b/iosApp/iosApp/ContentView.swift new file mode 100644 index 0000000..3cd5c32 --- /dev/null +++ b/iosApp/iosApp/ContentView.swift @@ -0,0 +1,21 @@ +import UIKit +import SwiftUI +import ComposeApp + +struct ComposeView: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> UIViewController { + MainViewControllerKt.MainViewController() + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} +} + +struct ContentView: View { + var body: some View { + ComposeView() + .ignoresSafeArea(.keyboard) // Compose has own keyboard handler + } +} + + + diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist new file mode 100644 index 0000000..412e378 --- /dev/null +++ b/iosApp/iosApp/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..4aa7c53 --- /dev/null +++ b/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift new file mode 100644 index 0000000..0648e86 --- /dev/null +++ b/iosApp/iosApp/iOSApp.swift @@ -0,0 +1,10 @@ +import SwiftUI + +@main +struct iOSApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 5eceb93..0000000 --- a/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':app' -rootProject.name = 'Rick and Morty' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..11ddb25 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,21 @@ +rootProject.name = "RickandMorty" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +pluginManagement { + repositories { + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + google() + gradlePluginPortal() + mavenCentral() + } +} + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } +} + +include(":composeApp") \ No newline at end of file