├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── weather
│ │ │ │ └── app
│ │ │ │ ├── SplashIntentHandler.kt
│ │ │ │ ├── IntentsReceiver.kt
│ │ │ │ ├── MainViewModel.kt
│ │ │ │ ├── FragmentsNavigator.kt
│ │ │ │ ├── IntentsHandler.kt
│ │ │ │ ├── WeatherApp.kt
│ │ │ │ └── MainActivity.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── app
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── app
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── cache
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── java
│ └── com
│ └── sample
│ └── cache
│ └── CacheAdapter.kt
├── core
├── .gitignore
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── core
│ │ ├── scenarios
│ │ ├── package-info.java
│ │ ├── cities
│ │ │ ├── ShowFavoriteCitiesUseCase.kt
│ │ │ ├── AddFavouriteCityUseCase.kt
│ │ │ ├── RemoveFavouriteCityUseCase.kt
│ │ │ ├── SearchForCitiesUseCase.kt
│ │ │ ├── CitySearchValidationUseCase.kt
│ │ │ └── CitiesRepository.kt
│ │ ├── weather
│ │ │ ├── ThreeDaysForecastUseCase.kt
│ │ │ └── WeatherRepository.kt
│ │ └── authentication
│ │ │ ├── LoggedInUserValidationUseCase.kt
│ │ │ ├── ForgotPasswordUseCase.kt
│ │ │ ├── RegisterUseCase.kt
│ │ │ ├── LoginUseCase.kt
│ │ │ ├── CredentialsValidationUseCase.kt
│ │ │ └── AuthenticationRepository.kt
│ │ ├── enities
│ │ ├── Errors.kt
│ │ └── Entities.kt
│ │ ├── ports
│ │ ├── PreferencesPort.kt
│ │ ├── LoggerPort.kt
│ │ ├── ResourcesPort.kt
│ │ ├── CachePort.kt
│ │ ├── DatabasePort.kt
│ │ └── ServerPort.kt
│ │ └── CoreIntegration.kt
└── build.gradle
├── database
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── database
│ │ │ └── DatabaseAdapter.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── database
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── database
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── logger
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── logger
│ │ │ └── LoggerAdapter.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── logger
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── logger
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── resources
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── resources
│ │ │ └── ResourcesAdapter.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── resources
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── resources
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── server
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── server
│ │ │ └── ServerAdapter.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── server
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── server
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── preferences
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── preferences
│ │ │ └── PreferencesAdapter.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── preferences
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── preferences
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── screen-login
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── login
│ │ │ └── LoginFragment.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── login
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── screen
│ │ └── login
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── screen-splash
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ └── strings.xml
│ │ │ └── layout
│ │ │ │ └── splash_fragment.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── splash
│ │ │ ├── SplashViewModel.kt
│ │ │ └── SplashFragment.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── splash
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── screen
│ │ └── splash
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── presentation-core
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── sample
│ │ │ │ └── presentation
│ │ │ │ ├── Presentation.kt
│ │ │ │ └── FragmentNameLogger.kt
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sample
│ │ │ └── presentation
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sample
│ │ └── presentation
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── screen-favourites
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── favourites
│ │ │ └── FavouritesFragment.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── favourites
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── screen
│ │ └── favourites
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── screen-forecast
├── .gitignore
├── consumer-rules.pro
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── screen
│ │ │ └── forecast
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── screen
│ │ └── forecast
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── README.md
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
├── codeStyles
│ ├── codeStyleConfig.xml
│ └── Project.xml
├── vcs.xml
├── kotlinc.xml
├── misc.xml
├── runConfigurations.xml
├── modules.xml
└── markdown-navigator.xml
├── settings.gradle
├── gradle.properties
├── .gitignore
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/cache/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/database/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/logger/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/logger/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/server/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/preferences/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/preferences/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/screen-login/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screen-splash/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/presentation-core/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screen-favourites/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screen-forecast/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/screen-forecast/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screen-login/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/screen-splash/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/presentation-core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/screen-favourites/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | App
3 |
4 |
--------------------------------------------------------------------------------
/presentation-core/src/main/java/com/sample/presentation/Presentation.kt:
--------------------------------------------------------------------------------
1 | package com.sample.presentation
2 |
3 |
--------------------------------------------------------------------------------
/database/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Database
3 |
4 |
--------------------------------------------------------------------------------
/logger/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Logger
3 |
4 |
--------------------------------------------------------------------------------
/server/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Server
3 |
4 |
--------------------------------------------------------------------------------
/resources/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Resources
3 |
4 |
--------------------------------------------------------------------------------
/preferences/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Preferences
3 |
4 |
--------------------------------------------------------------------------------
/screen-login/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Screen-Login
3 |
4 |
--------------------------------------------------------------------------------
/screen-splash/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Screen-Splash
3 |
4 |
--------------------------------------------------------------------------------
/presentation-core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Presentation
3 |
4 |
--------------------------------------------------------------------------------
/screen-forecast/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Screen-Forecast
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PortsAndAdaptersSample
2 | A sample project using the "Ports and Adapters" architecture, also called "Hexagonal" architecture
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/screen-favourites/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Screen-Favourites
3 |
4 |
--------------------------------------------------------------------------------
/logger/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/server/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/database/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/resources/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/screen-login/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/preferences/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/screen-forecast/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/screen-splash/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/screen-favourites/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/presentation-core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ahmed-Adel-Ismail/PortsAndAdaptersSample/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * this package is divided by use-cases / user-stories / scenarios
3 | */
4 | package com.sample.core.scenarios;
5 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/screen-login/src/main/java/com/screen/login/LoginFragment.kt:
--------------------------------------------------------------------------------
1 | package com.screen.login
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class LoginFragment : Fragment(){
6 |
7 |
8 |
9 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/enities/Errors.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.enities
2 |
3 | import java.lang.RuntimeException
4 |
5 | class ValidationException(message: String) : RuntimeException(message)
--------------------------------------------------------------------------------
/screen-favourites/src/main/java/com/screen/favourites/FavouritesFragment.kt:
--------------------------------------------------------------------------------
1 | package com.screen.favourites
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class FavouritesFragment : Fragment(){
6 |
7 | }
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/ShowFavoriteCitiesUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | @CitiesScenario
4 | suspend fun showFavouriteCities(repository: CitiesRepository = CitiesRepositoryImplementer) =
5 | repository.loadFavouriteCities()
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Nov 30 21:45:47 EET 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/weather/ThreeDaysForecastUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.weather
2 |
3 | @WeatherScenario
4 | suspend fun requestThreeDaysForecast(
5 | repository: WeatherRepository = WeatherRepositoryImplementer
6 | ) = repository.requestThreeDaysForecast()
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/LoggedInUserValidationUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | @AuthenticationScenario
4 | suspend fun isLoggedIn(
5 | repository: AuthenticationRepository = AuthenticationRepositoryImplementer
6 | ) = repository.loadToken() != null
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/PreferencesPort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | interface PreferencesPort {
4 |
5 | suspend fun save(key: String, value: T): T
6 |
7 | suspend fun load(key: String): T?
8 |
9 | suspend fun isSaved(key: String): Boolean
10 |
11 | suspend fun remove(key: String): Boolean
12 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/AddFavouriteCityUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | import com.sample.core.enities.City
4 |
5 | @CitiesScenario
6 | suspend fun addFavouriteCity(
7 | city: City,
8 | repository: CitiesRepository = CitiesRepositoryImplementer
9 | ) = repository.addFavouriteCity(city)
10 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app',
2 | ':cache',
3 | ':core',
4 | ':preferences',
5 | ':server',
6 | ':database',
7 | ':screen-login',
8 | ':screen-favourites',
9 | ':screen-forecast',
10 | ':presentation-core',
11 | ':screen-splash',
12 | ':logger',
13 | ':resources'
--------------------------------------------------------------------------------
/cache/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java-library'
2 | apply plugin: 'kotlin'
3 |
4 | dependencies {
5 | implementation fileTree(dir: 'libs', include: ['*.jar'])
6 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
7 | implementation project(path: ':core')
8 | }
9 |
10 | sourceCompatibility = "8"
11 | targetCompatibility = "8"
12 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/RemoveFavouriteCityUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | import com.sample.core.enities.City
4 |
5 | @CitiesScenario
6 | suspend fun removeFavouriteCity(
7 | city: City,
8 | repository: CitiesRepository = CitiesRepositoryImplementer
9 | ) = repository.removeFavouriteCity(city)
10 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/LoggerPort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | interface LoggerPort {
4 |
5 | fun log(tag: String, message: Any?)
6 |
7 | fun warn(tag: String, message: Any?)
8 |
9 | fun error(tag: String, message: Any?)
10 |
11 | fun error(tag: String, throwable: Throwable?)
12 |
13 | fun error(throwable: Throwable?)
14 |
15 | }
--------------------------------------------------------------------------------
/presentation-core/src/main/java/com/sample/presentation/FragmentNameLogger.kt:
--------------------------------------------------------------------------------
1 | package com.sample.presentation
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import androidx.fragment.app.FragmentManager
6 |
7 | class FragmentNameLogger : FragmentManager.FragmentLifecycleCallbacks() {
8 |
9 | override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
10 |
11 | }
12 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/ResourcesPort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | interface ResourcesPort {
4 |
5 | suspend fun localizedString(stringResources: StringResources): String
6 |
7 | }
8 |
9 | sealed class StringResources(val name: String) {
10 | object InvalidCredentials : StringResources("invalid_credentials")
11 | object InvalidCitySearchName : StringResources("invalid_city_search_name")
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/SearchForCitiesUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | import com.sample.core.enities.CitySearchName
4 |
5 | @CitiesScenario
6 | suspend fun searchForCity(
7 | citySearchName: CitySearchName,
8 | isValidInput: suspend (String?) -> Boolean = { it.isValidCitySearchName() },
9 | repository: CitiesRepository = CitiesRepositoryImplementer
10 | ) {
11 | TODO()
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sample/app/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.app
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/logger/src/test/java/com/sample/logger/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.logger
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/server/src/test/java/com/sample/server/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.server
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/ForgotPasswordUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | import com.sample.core.enities.Username
4 |
5 | @AuthenticationScenario
6 | suspend fun forgotPassword(
7 | username: Username,
8 | isValidInput: suspend (String?) -> Boolean = { it.isValidCredential() },
9 | authenticationRepository: AuthenticationRepository = AuthenticationRepositoryImplementer
10 | ) {
11 | TODO()
12 | }
--------------------------------------------------------------------------------
/database/src/test/java/com/sample/database/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.database
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/screen-login/src/test/java/com/screen/login/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.login
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/screen-splash/src/test/java/com/screen/splash/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.splash
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/resources/src/test/java/com/sample/resources/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.resources
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/screen-forecast/src/test/java/com/screen/forecast/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.forecast
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/preferences/src/test/java/com/sample/preferences/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.preferences
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/presentation-core/src/test/java/com/sample/presentation/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.presentation
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/screen-favourites/src/test/java/com/screen/favourites/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.favourites
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/CachePort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | interface CachePort {
4 |
5 | fun save(key: String, value: T): T
6 |
7 | fun load(key: String): T?
8 |
9 | fun isSaved(key: String): Boolean
10 |
11 | fun remove(key: String): Boolean
12 |
13 | fun observeOn(key: String, vararg states: ObserveOnStates = arrayOf(ObserveOnStates.SAVE))
14 |
15 | enum class ObserveOnStates {
16 | SAVE, REMOVE, LOAD
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/DatabasePort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | import com.sample.core.enities.City
4 | import com.sample.core.enities.CitySearchName
5 |
6 | interface DatabasePort{
7 |
8 | suspend fun queryCityByName(citySearchName: CitySearchName) : List?
9 | suspend fun queryAllFavouriteCities(): List?
10 | suspend fun insertFavouriteCity(city: City) : City
11 | suspend fun deleteFavouriteCity(city: City) : City
12 |
13 |
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/screen-splash/src/main/res/layout/splash_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/SplashIntentHandler.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.content.Intent
4 | import com.screen.favourites.FavouritesFragment
5 | import com.screen.login.LoginFragment
6 | import com.screen.splash.EXTRA_SPLASH_LOGGED_IN_USER
7 |
8 | fun MainActivity.handleSplashIntent(intent1: Intent) {
9 | if (intent1.getBooleanExtra(EXTRA_SPLASH_LOGGED_IN_USER, false)) {
10 | replaceFragment(FavouritesFragment())
11 | } else {
12 | replaceFragment(LoginFragment())
13 | }
14 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/RegisterUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | import com.sample.core.enities.Password
4 | import com.sample.core.enities.Username
5 |
6 | @AuthenticationScenario
7 | suspend fun register(
8 | username: Username,
9 | password: Password,
10 | inputValidation: suspend (String?) -> Boolean = { it.isValidCredential() },
11 | authenticationRepository: AuthenticationRepository = AuthenticationRepositoryImplementer
12 | ) {
13 | TODO()
14 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/LoginUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | import com.sample.core.enities.Password
4 | import com.sample.core.enities.Username
5 |
6 | @AuthenticationScenario
7 | suspend fun login(
8 | username: Username,
9 | password: Password,
10 | inputValidation: suspend (String?) -> Boolean = { it.isValidCredential() },
11 | authenticationRepository: AuthenticationRepository = AuthenticationRepositoryImplementer
12 | ) {
13 | TODO()
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/ports/ServerPort.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.ports
2 |
3 | import com.sample.core.enities.Forecast
4 | import com.sample.core.enities.Password
5 | import com.sample.core.enities.Token
6 | import com.sample.core.enities.Username
7 |
8 | interface ServerPort {
9 |
10 | suspend fun login(username: Username, password: Password): Token
11 | suspend fun register(username: Username, password: Password): Token
12 | suspend fun forgotPassword(username: Username): Username
13 | suspend fun requestThreeDaysForecast(): List
14 |
15 | }
--------------------------------------------------------------------------------
/resources/src/main/java/com/sample/resources/ResourcesAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.resources
2 |
3 | import android.content.Context
4 | import com.sample.core.IntegrationDsl
5 | import com.sample.core.ports.ResourcesPort
6 | import com.sample.core.ports.StringResources
7 |
8 | class ResourcesAdapter @IntegrationDsl constructor(val context: Context) : ResourcesPort {
9 |
10 | override suspend fun localizedString(stringResources: StringResources): String {
11 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
12 | }
13 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/weather/WeatherRepository.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.weather
2 |
3 | import com.sample.core.enities.Forecast
4 | import com.sample.core.server
5 |
6 | @DslMarker
7 | annotation class WeatherScenario
8 |
9 | interface WeatherRepository {
10 |
11 | @WeatherScenario
12 | suspend fun requestThreeDaysForecast() : List
13 |
14 | }
15 |
16 |
17 | internal object WeatherRepositoryImplementer : WeatherRepository{
18 | override suspend fun requestThreeDaysForecast(): List =
19 | server.requestThreeDaysForecast()
20 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/CitySearchValidationUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | import com.sample.core.enities.ValidationException
4 |
5 |
6 | private const val MINIMUM_LETTERS_COUNT = 3
7 | private const val MAXIMUM_LETTERS_COUNT = 20
8 |
9 | @CitiesScenario
10 | @Throws(ValidationException::class)
11 | internal suspend fun String?.isValidCitySearchName(
12 | minimumLettersCount: Int = MINIMUM_LETTERS_COUNT,
13 | maximumLettersCount: Int = MAXIMUM_LETTERS_COUNT,
14 | repository: CitiesRepository = CitiesRepositoryImplementer
15 | ): Boolean {
16 | TODO()
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/IntentsReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import androidx.lifecycle.lifecycleScope
7 | import kotlinx.coroutines.launch
8 |
9 | class IntentsReceiver(private val mainActivity: MainActivity) : BroadcastReceiver() {
10 | override fun onReceive(context: Context?, intent: Intent) {
11 | mainActivity.onIntentReceived(intent)
12 | }
13 | }
14 |
15 | fun MainActivity.onIntentReceived(intent: Intent) {
16 | lifecycleScope.launch {
17 | viewModel.intents.send(intent)
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.content.Intent
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import kotlinx.coroutines.channels.Channel
7 | import kotlinx.coroutines.launch
8 |
9 | class MainViewModel(val intents: Channel = Channel(Channel.UNLIMITED)) : ViewModel() {
10 |
11 | init {
12 | viewModelScope.launch {
13 | intents.send(Intent(ACTION_INITIALIZE))
14 | }
15 | }
16 |
17 | override fun onCleared() {
18 | intents.cancel()
19 | super.onCleared()
20 | }
21 | }
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/FragmentsNavigator.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.sample.app.R
5 |
6 | fun MainActivity.addFragment(newFragment: Fragment) {
7 | supportFragmentManager.beginTransaction()
8 | .add(R.id.mainFragmentContainer, newFragment)
9 | .addToBackStack(newFragment.javaClass.name)
10 | .commit()
11 | }
12 |
13 | fun MainActivity.replaceFragment(newFragment: Fragment) {
14 | supportFragmentManager.beginTransaction()
15 | .replace(R.id.mainFragmentContainer, newFragment, newFragment.javaClass.name)
16 | .addToBackStack(newFragment.javaClass.name)
17 | .commit()
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/IntentsHandler.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.content.Intent
4 | import android.content.IntentFilter
5 | import com.screen.splash.ACTION_SPLASH_FINISHED
6 | import com.screen.splash.SplashFragment
7 |
8 | const val ACTION_INITIALIZE = "com.weather.app.ACTION_INITIALIZE"
9 |
10 | fun intentsFilter() = IntentFilter(
11 | ACTION_INITIALIZE,
12 | ACTION_SPLASH_FINISHED
13 | )
14 |
15 | fun MainActivity.onHandleIntent(intent: Intent) = with(intent) {
16 | when (action) {
17 | ACTION_INITIALIZE -> addFragment(SplashFragment())
18 | ACTION_SPLASH_FINISHED -> handleSplashIntent(this)
19 | }
20 | }
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/sample/app/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.app
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.app", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/logger/src/androidTest/java/com/sample/logger/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.logger
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.logger.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screen-login/src/androidTest/java/com/screen/login/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.login
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.screen.login.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/server/src/androidTest/java/com/sample/server/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.server
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.server.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/database/src/androidTest/java/com/sample/database/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.database
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.database.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screen-splash/src/androidTest/java/com/screen/splash/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.splash
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.screen.splash.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/resources/src/androidTest/java/com/sample/resources/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.resources
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.resources.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screen-forecast/src/androidTest/java/com/screen/forecast/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.forecast
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.screen.forecast.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/logger/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/preferences/src/androidTest/java/com/sample/preferences/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.preferences
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.preferences.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screen-favourites/src/androidTest/java/com/screen/favourites/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.screen.favourites
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.screen.favourites.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/server/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/database/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/preferences/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/resources/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/screen-login/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/presentation-core/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/presentation-core/src/androidTest/java/com/sample/presentation/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sample.presentation
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sample.presentation.test", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screen-favourites/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/screen-forecast/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/screen-splash/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/screen-splash/src/main/java/com/screen/splash/SplashViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.screen.splash
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.viewModelScope
5 | import com.sample.core.scenarios.authentication.isLoggedIn
6 | import kotlinx.coroutines.Dispatchers.IO
7 | import kotlinx.coroutines.channels.Channel
8 | import kotlinx.coroutines.launch
9 |
10 | class SplashViewModel(
11 | val loggedInUser: Channel = Channel(Channel.UNLIMITED),
12 | val errorChannel: Channel = Channel(Channel.RENDEZVOUS)
13 | ) : ViewModel() {
14 |
15 | init {
16 | viewModelScope.launch(IO) {
17 | runCatching { isLoggedIn() }
18 | .onFailure { errorChannel.send(it) }
19 | .getOrDefault(false)
20 | .also { loggedInUser.send(it) }
21 | }
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/CredentialsValidationUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | import com.sample.core.enities.ValidationException
4 |
5 | private const val MINIMUM_LETTERS_COUNT = 4
6 | private const val MAXIMUM_LETTERS_COUNT = 12
7 | private const val MINIMUM_CAPITAL_LETTERS_COUNT = 1
8 | private const val MINIMUM_SPECIAL_CHARACTERS_COUNT = 1
9 |
10 | @AuthenticationScenario
11 | @Throws(ValidationException::class)
12 | internal suspend fun String?.isValidCredential(
13 | minimumLettersCount: Int = MINIMUM_LETTERS_COUNT,
14 | maximumLettersCount: Int = MAXIMUM_LETTERS_COUNT,
15 | minimumCapitalLettersCount: Int = MINIMUM_CAPITAL_LETTERS_COUNT,
16 | maximumSpecialCharactersCount: Int = MINIMUM_SPECIAL_CHARACTERS_COUNT,
17 | repository: AuthenticationRepository = AuthenticationRepositoryImplementer
18 | ): Boolean {
19 | TODO()
20 | }
--------------------------------------------------------------------------------
/core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java-library'
2 | apply plugin: 'kotlin'
3 |
4 | dependencies {
5 | api fileTree(dir: 'libs', include: ['*.jar'])
6 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
7 | api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
8 | api 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2'
9 | }
10 |
11 | sourceCompatibility = "8"
12 | targetCompatibility = "8"
13 |
14 | buildscript {
15 | repositories {
16 | mavenCentral()
17 | }
18 | dependencies {
19 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
20 | }
21 | }
22 | repositories {
23 | mavenCentral()
24 | }
25 | compileKotlin {
26 | kotlinOptions {
27 | jvmTarget = "1.8"
28 | freeCompilerArgs = ["-XXLanguage:+InlineClasses"]
29 | }
30 | }
31 |
32 | compileTestKotlin {
33 | kotlinOptions {
34 | jvmTarget = "1.8"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/WeatherApp.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.app.Application
4 | import com.sample.cache.CacheAdapter
5 | import com.sample.core.Core
6 | import com.sample.database.DatabaseAdapter
7 | import com.sample.logger.LoggerAdapter
8 | import com.sample.preferences.PreferencesAdapter
9 | import com.sample.resources.ResourcesAdapter
10 | import com.sample.server.ServerAdapter
11 |
12 | class WeatherApp : Application() {
13 |
14 |
15 | override fun onCreate() {
16 | super.onCreate()
17 |
18 | Core {
19 | initialize with DatabaseAdapter(applicationContext)
20 | and with PreferencesAdapter(applicationContext)
21 | and with CacheAdapter()
22 | and with ServerAdapter(applicationContext)
23 | and with ResourcesAdapter(applicationContext)
24 | and with LoggerAdapter(applicationContext)
25 | }
26 | }
27 |
28 |
29 | }
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/preferences/src/main/java/com/sample/preferences/PreferencesAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.preferences
2 |
3 | import android.content.Context
4 | import com.sample.core.IntegrationDsl
5 | import com.sample.core.ports.PreferencesPort
6 |
7 | class PreferencesAdapter @IntegrationDsl constructor(val context: Context) : PreferencesPort{
8 |
9 | override suspend fun save(key: String, value: T): T {
10 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
11 | }
12 |
13 | override suspend fun load(key: String): T? {
14 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
15 | }
16 |
17 | override suspend fun isSaved(key: String): Boolean {
18 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
19 | }
20 |
21 | override suspend fun remove(key: String): Boolean {
22 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
23 | }
24 | }
--------------------------------------------------------------------------------
/screen-login/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
32 | implementation project(path: ':presentation-core')
33 | }
34 |
--------------------------------------------------------------------------------
/screen-forecast/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
32 | implementation project(path: ':presentation-core')
33 | }
34 |
--------------------------------------------------------------------------------
/screen-favourites/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
32 |
33 | implementation project(path: ':presentation-core')
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/enities/Entities.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.enities
2 |
3 | import java.io.Serializable
4 |
5 | inline class Username(
6 | val value: String? = null
7 | ) : Serializable
8 |
9 | inline class Password(
10 | val value: String? = null
11 | ) : Serializable
12 |
13 |
14 | inline class Token(
15 | val value: String? = null
16 | ) : Serializable
17 |
18 | data class Event(
19 | val key: String,
20 | val extras: Map? = null
21 | ) : Serializable
22 |
23 | data class City(
24 | val id: CityId,
25 | val name: CityName
26 | ) : Serializable
27 |
28 | inline class CityId(
29 | val value: Long
30 | ) : Serializable
31 |
32 | inline class CityName(
33 | val value: String
34 | ) : Serializable
35 |
36 | inline class CitySearchName(
37 | val value: String
38 | ) : Serializable
39 |
40 | data class Forecast(
41 | val dateText: String? = null,
42 | val cloudiness: String? = null,
43 | val humidity: String? = null,
44 | val temperature: String? = null,
45 | val weather: String? = null,
46 | val windSpeed: String? = null
47 | ) : Serializable
--------------------------------------------------------------------------------
/cache/src/main/java/com/sample/cache/CacheAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.cache
2 |
3 | import com.sample.core.IntegrationDsl
4 | import com.sample.core.ports.CachePort
5 |
6 | class CacheAdapter @IntegrationDsl constructor() : CachePort{
7 |
8 | override fun save(key: String, value: T): T {
9 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
10 | }
11 |
12 | override fun load(key: String): T? {
13 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
14 | }
15 |
16 | override fun isSaved(key: String): Boolean {
17 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
18 | }
19 |
20 | override fun remove(key: String): Boolean {
21 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
22 | }
23 |
24 | override fun observeOn(key: String, vararg states: CachePort.ObserveOnStates) {
25 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
26 | }
27 | }
--------------------------------------------------------------------------------
/screen-splash/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
33 | implementation project(path: ':presentation-core')
34 | }
35 |
--------------------------------------------------------------------------------
/database/src/main/java/com/sample/database/DatabaseAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.database
2 |
3 | import android.content.Context
4 | import com.sample.core.IntegrationDsl
5 | import com.sample.core.enities.City
6 | import com.sample.core.enities.CitySearchName
7 | import com.sample.core.ports.DatabasePort
8 |
9 | class DatabaseAdapter @IntegrationDsl constructor(val context: Context) : DatabasePort{
10 |
11 |
12 | override suspend fun queryCityByName(citySearchName: CitySearchName): List? {
13 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
14 | }
15 |
16 | override suspend fun queryAllFavouriteCities(): List? {
17 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
18 | }
19 |
20 | override suspend fun insertFavouriteCity(city: City): City {
21 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
22 | }
23 |
24 | override suspend fun deleteFavouriteCity(city: City): City {
25 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
26 | }
27 | }
--------------------------------------------------------------------------------
/logger/src/main/java/com/sample/logger/LoggerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.logger
2 |
3 | import android.content.Context
4 | import com.sample.core.IntegrationDsl
5 | import com.sample.core.ports.LoggerPort
6 |
7 | class LoggerAdapter @IntegrationDsl constructor(val context: Context) : LoggerPort{
8 |
9 | override fun log(tag: String, message: Any?) {
10 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
11 | }
12 |
13 | override fun warn(tag: String, message: Any?) {
14 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
15 | }
16 |
17 | override fun error(tag: String, message: Any?) {
18 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
19 | }
20 |
21 | override fun error(tag: String, throwable: Throwable?) {
22 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
23 | }
24 |
25 | override fun error(throwable: Throwable?) {
26 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
27 | }
28 | }
--------------------------------------------------------------------------------
/database/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | implementation 'androidx.appcompat:appcompat:1.1.0'
31 | implementation 'androidx.core:core-ktx:1.1.0'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
35 | implementation project(path: ':core')
36 | }
37 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
19 | # AndroidX package structure to make it clearer which packages are bundled with the
20 | # Android operating system, and which are packaged with your app's APK
21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
22 | android.useAndroidX=true
23 | # Automatically convert third-party libraries to use AndroidX
24 | android.enableJetifier=true
25 |
26 | # Kotlin code style for this project: "official" or "obsolete":
27 | kotlin.code.style=official
28 |
--------------------------------------------------------------------------------
/logger/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | implementation 'androidx.appcompat:appcompat:1.1.0'
31 | implementation 'androidx.core:core-ktx:1.1.0'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
35 | implementation project(path: ':core')
36 | }
37 |
--------------------------------------------------------------------------------
/server/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | implementation 'androidx.appcompat:appcompat:1.1.0'
31 | implementation 'androidx.core:core-ktx:1.1.0'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
35 | implementation project(path: ':core')
36 | }
37 |
--------------------------------------------------------------------------------
/preferences/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | implementation 'androidx.appcompat:appcompat:1.1.0'
31 | implementation 'androidx.core:core-ktx:1.1.0'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
35 | implementation project(path: ':core')
36 | }
37 |
--------------------------------------------------------------------------------
/resources/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion compile_sdk_version
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
30 | implementation 'androidx.appcompat:appcompat:1.1.0'
31 | implementation 'androidx.core:core-ktx:1.1.0'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
35 | implementation project(path: ':core')
36 | }
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # IntelliJ
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/assetWizardSettings.xml
41 | .idea/dictionaries
42 | .idea/libraries
43 | .idea/caches
44 |
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | # fastlane
61 | fastlane/report.xml
62 | fastlane/Preview.html
63 | fastlane/screenshots
64 | fastlane/test_output
65 | fastlane/readme.md
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/weather/app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.weather.app
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import androidx.lifecycle.ViewModelProviders
6 | import androidx.lifecycle.lifecycleScope
7 | import com.sample.app.R
8 | import kotlinx.coroutines.launch
9 |
10 | /**
11 | * this class is responsible for App navigation
12 | */
13 | class MainActivity : AppCompatActivity() {
14 |
15 | val intentsReceiver by lazy { IntentsReceiver(this) }
16 | val viewModel by lazy { ViewModelProviders.of(this).get(MainViewModel::class.java) }
17 |
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.activity_main)
22 | handleIntents()
23 | }
24 |
25 |
26 | override fun onDestroy() {
27 | unHandleIntents()
28 | super.onDestroy()
29 | }
30 | }
31 |
32 |
33 | fun MainActivity.handleIntents() {
34 | registerReceiver(intentsReceiver, intentsFilter())
35 | lifecycleScope.launch {
36 | for (intent in viewModel.intents) {
37 | onHandleIntent(intent)
38 | }
39 | }
40 | }
41 |
42 |
43 | fun MainActivity.unHandleIntents() {
44 | unregisterReceiver(intentsReceiver)
45 | }
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/server/src/main/java/com/sample/server/ServerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sample.server
2 |
3 | import android.content.Context
4 | import com.sample.core.IntegrationDsl
5 | import com.sample.core.enities.Forecast
6 | import com.sample.core.enities.Password
7 | import com.sample.core.enities.Token
8 | import com.sample.core.enities.Username
9 | import com.sample.core.ports.ServerPort
10 |
11 | class ServerAdapter @IntegrationDsl constructor(private val context: Context) : ServerPort {
12 |
13 | override suspend fun login(username: Username, password: Password): Token {
14 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
15 | }
16 |
17 | override suspend fun register(username: Username, password: Password): Token {
18 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
19 | }
20 |
21 | override suspend fun forgotPassword(username: Username): Username {
22 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
23 | }
24 |
25 | override suspend fun requestThreeDaysForecast(): List {
26 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/CoreIntegration.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core
2 |
3 | import com.sample.core.ports.*
4 |
5 | internal lateinit var cache: CachePort
6 | internal lateinit var database: DatabasePort
7 | internal lateinit var logger: LoggerPort
8 | internal lateinit var preferences: PreferencesPort
9 | internal lateinit var resources: ResourcesPort
10 | internal lateinit var server: ServerPort
11 |
12 | /**
13 | * an annotation that marks any code related to integration with the core module
14 | */
15 | @DslMarker
16 | annotation class IntegrationDsl
17 |
18 | /**
19 | * a function for initializing the Core module, it is considered as a Factory function but
20 | * for the entire module, not just a class
21 | */
22 | @IntegrationDsl
23 | @Suppress("FunctionName")
24 | fun Core(integrate: AdaptersFactoryProvider.() -> Unit) {
25 | integrate(AdaptersFactoryProvider())
26 | }
27 |
28 | class AdaptersFactoryProvider {
29 | @IntegrationDsl
30 | val initialize by lazy { AdaptersFactory() }
31 |
32 | @IntegrationDsl
33 | val and by lazy { initialize }
34 | }
35 |
36 | class AdaptersFactory {
37 |
38 | @IntegrationDsl
39 | infix fun with(port: Any) {
40 | when (port) {
41 | is ServerPort -> server = port
42 | is DatabasePort -> database = port
43 | is PreferencesPort -> preferences = port
44 | is ResourcesPort -> resources = port
45 | is CachePort -> cache = port
46 | is LoggerPort -> logger = port
47 | }
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/presentation-core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 |
6 | compileSdkVersion = compile_sdk_version
7 |
8 | defaultConfig {
9 | minSdkVersion min_sdk_version
10 | targetSdkVersion target_sdk_version
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles 'consumer-rules.pro'
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 |
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
32 |
33 | api fileTree(dir: 'libs', include: ['*.jar'])
34 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
35 | api 'androidx.constraintlayout:constraintlayout:1.1.3'
36 | api 'androidx.appcompat:appcompat:1.1.0'
37 | api 'androidx.core:core-ktx:1.1.0'
38 | api 'androidx.fragment:fragment-ktx:1.2.0-rc03'
39 | api 'androidx.lifecycle:lifecycle-extensions:2.1.0'
40 | api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
41 | api 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-rc03'
42 |
43 |
44 | api project(path: ':core')
45 | }
46 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/cities/CitiesRepository.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.cities
2 |
3 | import com.sample.core.database
4 | import com.sample.core.enities.City
5 | import com.sample.core.enities.CitySearchName
6 | import com.sample.core.ports.ResourcesPort
7 | import com.sample.core.ports.StringResources
8 | import com.sample.core.resources
9 |
10 | @DslMarker
11 | annotation class CitiesScenario
12 |
13 | interface CitiesRepository {
14 |
15 | @CitiesScenario
16 | suspend fun searchCityByName(citySearchName: CitySearchName): List?
17 |
18 | @CitiesScenario
19 | suspend fun loadFavouriteCities(): List?
20 |
21 | @CitiesScenario
22 | suspend fun addFavouriteCity(city: City): City
23 |
24 | @CitiesScenario
25 | suspend fun removeFavouriteCity(city: City): City
26 |
27 | @CitiesScenario
28 | suspend fun loadInvalidCitySearchNameMessage(): String
29 |
30 | }
31 |
32 | internal object CitiesRepositoryImplementer : CitiesRepository {
33 |
34 | override suspend fun searchCityByName(citySearchName: CitySearchName): List? =
35 | database.queryCityByName(citySearchName)
36 |
37 | override suspend fun loadFavouriteCities(): List? =
38 | database.queryAllFavouriteCities()
39 |
40 | override suspend fun addFavouriteCity(city: City) =
41 | database.insertFavouriteCity(city)
42 |
43 | override suspend fun removeFavouriteCity(city: City) =
44 | database.deleteFavouriteCity(city)
45 |
46 | override suspend fun loadInvalidCitySearchNameMessage() =
47 | resources.localizedString(StringResources.InvalidCitySearchName)
48 | }
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion compile_sdk_version
9 | defaultConfig {
10 | applicationId "com.weather.app"
11 | minSdkVersion min_sdk_version
12 | targetSdkVersion target_sdk_version
13 | versionCode 1
14 | versionName "1.0"
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 |
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | testImplementation 'junit:junit:4.12'
29 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
30 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
31 |
32 |
33 | implementation project(path: ':screen-favourites')
34 | implementation project(path: ':screen-forecast')
35 | implementation project(path: ':screen-login')
36 | implementation project(path: ':screen-splash')
37 | implementation project(path: ':presentation-core')
38 |
39 |
40 | implementation project(path: ':server')
41 | implementation project(path: ':database')
42 | implementation project(path: ':preferences')
43 | implementation project(path: ':logger')
44 | implementation project(path: ':resources')
45 | implementation project(path: ':cache')
46 | implementation project(path: ':core')
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/screen-splash/src/main/java/com/screen/splash/SplashFragment.kt:
--------------------------------------------------------------------------------
1 | package com.screen.splash
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.Toast
9 | import androidx.fragment.app.Fragment
10 | import androidx.lifecycle.ViewModelProviders
11 | import androidx.lifecycle.lifecycleScope
12 | import kotlinx.coroutines.launch
13 |
14 |
15 | const val ACTION_SPLASH_FINISHED = "com.screen.splash.ACTION_SPLASH_FINISHED"
16 | const val EXTRA_SPLASH_LOGGED_IN_USER = "com.screen.splash.EXTRA_SPLASH_LOGGED_IN_USER"
17 |
18 |
19 | class SplashFragment : Fragment() {
20 |
21 | private val viewModel by lazy {
22 | ViewModelProviders.of(this).get(SplashViewModel::class.java)
23 | }
24 |
25 | override fun onCreateView(
26 | inflater: LayoutInflater, container: ViewGroup?,
27 | savedInstanceState: Bundle?
28 | ): View? {
29 | return inflater.inflate(R.layout.splash_fragment, container, false)
30 | }
31 |
32 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
33 |
34 | lifecycleScope.launch {
35 | for (error in viewModel.errorChannel) {
36 | Toast.makeText(context, error.message ?: error.toString(), Toast.LENGTH_LONG).show()
37 | }
38 | }
39 |
40 | lifecycleScope.launch {
41 | for (isLoggedIn in viewModel.loggedInUser) {
42 | Intent(ACTION_SPLASH_FINISHED)
43 | .putExtra(EXTRA_SPLASH_LOGGED_IN_USER, isLoggedIn)
44 | .let { activity?.sendBroadcast(it) }
45 | }
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/core/src/main/java/com/sample/core/scenarios/authentication/AuthenticationRepository.kt:
--------------------------------------------------------------------------------
1 | package com.sample.core.scenarios.authentication
2 |
3 | import com.sample.core.enities.Password
4 | import com.sample.core.enities.Token
5 | import com.sample.core.enities.Username
6 | import com.sample.core.ports.ResourcesPort
7 | import com.sample.core.ports.StringResources
8 | import com.sample.core.preferences
9 | import com.sample.core.resources
10 | import com.sample.core.server
11 |
12 | @DslMarker
13 | annotation class AuthenticationScenario
14 |
15 | interface AuthenticationRepository {
16 |
17 | @AuthenticationScenario
18 | suspend fun requestLogin(username: Username, password: Password): Token
19 |
20 | @AuthenticationScenario
21 | suspend fun requestRegister(username: Username, password: Password): Token
22 |
23 | @AuthenticationScenario
24 | suspend fun requestForgotPassword(username: Username): Username
25 |
26 | @AuthenticationScenario
27 | suspend fun saveToken(token: Token): Token
28 |
29 | @AuthenticationScenario
30 | suspend fun loadToken(): Token?
31 |
32 | @AuthenticationScenario
33 | suspend fun loadInvalidCredentialsMessage(): String
34 |
35 | }
36 |
37 |
38 | private const val KEY_TOKEN = "com.sample.core.scenarios.authentication.KEY_TOKEN"
39 |
40 | internal object AuthenticationRepositoryImplementer : AuthenticationRepository {
41 |
42 | override suspend fun requestLogin(username: Username, password: Password): Token =
43 | server.login(username, password)
44 |
45 | override suspend fun requestRegister(username: Username, password: Password): Token =
46 | server.register(username, password)
47 |
48 | override suspend fun requestForgotPassword(username: Username) =
49 | server.forgotPassword(username)
50 |
51 | override suspend fun saveToken(token: Token): Token =
52 | preferences.save(KEY_TOKEN, token)
53 |
54 | override suspend fun loadToken(): Token? =
55 | preferences.load(KEY_TOKEN)
56 |
57 | override suspend fun loadInvalidCredentialsMessage() =
58 | resources.localizedString(StringResources.InvalidCredentials)
59 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | xmlns:android
23 |
24 | ^$
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | xmlns:.*
34 |
35 | ^$
36 |
37 |
38 | BY_NAME
39 |
40 |
41 |
42 |
43 |
44 |
45 | .*:id
46 |
47 | http://schemas.android.com/apk/res/android
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | .*:name
57 |
58 | http://schemas.android.com/apk/res/android
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | name
68 |
69 | ^$
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | style
79 |
80 | ^$
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | .*
90 |
91 | ^$
92 |
93 |
94 | BY_NAME
95 |
96 |
97 |
98 |
99 |
100 |
101 | .*
102 |
103 | http://schemas.android.com/apk/res/android
104 |
105 |
106 | ANDROID_ATTRIBUTE_ORDER
107 |
108 |
109 |
110 |
111 |
112 |
113 | .*
114 |
115 | .*
116 |
117 |
118 | BY_NAME
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------