From dfabfa16cc30375f653aad4117d5143e9f0a0e44 Mon Sep 17 00:00:00 2001 From: Kaung Khant Soe Date: Tue, 5 Jul 2022 13:13:21 +0700 Subject: [PATCH 1/9] [#241] Update kscript for app name argument --- scripts/new_project.kts | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/scripts/new_project.kts b/scripts/new_project.kts index cd3fc7fa4..981186fcc 100644 --- a/scripts/new_project.kts +++ b/scripts/new_project.kts @@ -6,28 +6,43 @@ object NewProject { private const val DOT_SEPARATOR = "." private const val KEY_APP_NAME = "app-name" private const val KEY_PACKAGE_NAME = "package-name" + private const val MINUS_SEPARATOR = "-" + private const val SPACE_SEPARATOR = " " private const val TEMPLATE_APP_NAME = "Coroutine Template" private const val TEMPLATE_APPLICATION_CLASS_NAME = "CoroutineTemplateApplication" private const val TEMPLATE_FOLDER_NAME = "CoroutineTemplate" private const val TEMPLATE_PACKAGE_NAME = "co.nimblehq.coroutine" - private const val PATTERN_APP = "^[A-Z][a-zA-Z0-9\\s]*$" + private const val PATTERN_APP = "^([A-Z][a-zA-Z0-9\\s]*)|([a-z][a-z0-9-]*)$" private const val PATTERN_PACKAGE = "^[a-z]+(\\.[a-z][a-z0-9]*)+$" private val modules = listOf("app", "data", "domain") private val fileSeparator = File.separator - private var appName = "" + private var appName: String = "" + set(value) { + field = if (value.contains(MINUS_SEPARATOR)) { + projectFolderName = value + value.replace(MINUS_SEPARATOR, SPACE_SEPARATOR).uppercaseEveryFirstCharacter() + } else { + value.uppercaseEveryFirstCharacter().also { + projectFolderName = it.getStringWithoutSpace() + } + } + } + private var packageName = "" private val appNameWithoutSpace: String - get() = appName.replace(" ", "") + get() = appName.getStringWithoutSpace() private val applicationClassName: String get() = "${appNameWithoutSpace}Application" + private var projectFolderName: String = "" + private val projectPath: String - get() = rootPath + appNameWithoutSpace + get() = rootPath + projectFolderName private val rootPath: String get() = System.getProperty("user.dir").replace("scripts", "") @@ -65,7 +80,7 @@ object NewProject { private fun validateAppName(value: String) { if (PATTERN_APP.toRegex().matches(value)) { - appName = value + appName = value.trim() } else { showErrorMessage("ERROR: Invalid App Name: $value (needs to follow standard pattern {MyProject} or {My Project})") } @@ -73,7 +88,7 @@ object NewProject { private fun validatePackageName(value: String) { if (PATTERN_PACKAGE.toRegex().matches(value)) { - packageName = value + packageName = value.trim() } else { showErrorMessage("ERROR: Invalid Package Name: $value (needs to follow standard pattern {com.example.package})") } @@ -137,7 +152,7 @@ object NewProject { private fun renamePackageNameWithinFiles() { showMessage("=> 🔎 Renaming package name within files...") File(projectPath) - ?.walk() + .walk() .filter { it.name.endsWith(".kt") || it.name.endsWith(".xml") } .forEach { filePath -> rename( @@ -151,7 +166,7 @@ object NewProject { private fun renameApplicationClass() { showMessage("=> 🔎 Renaming application class...") File(projectPath) - ?.walk() + .walk() .filter { it.name == "$TEMPLATE_APPLICATION_CLASS_NAME.kt" || it.name == "AndroidManifest.xml" } .forEach { file -> rename( @@ -192,14 +207,14 @@ object NewProject { process.inputStream.reader().forEachLine { println(it) } val exitValue = process.waitFor() if (exitValue != 0) { - showErrorMessage("❌ Something went wrong!", exitValue) + showErrorMessage("❌ Something went wrong! when executing command: $command", exitValue) } } private fun renameAppName() { showMessage("=> 🔎 Renaming app name...") File(projectPath) - ?.walk() + .walk() .filter { it.name == "strings.xml" } .forEach { filePath -> rename( @@ -225,6 +240,16 @@ object NewProject { println("\n${message}\n") System.exit(exitCode) } + + private fun String.uppercaseEveryFirstCharacter(): String { + return this.split(SPACE_SEPARATOR).joinToString(separator = SPACE_SEPARATOR) { string -> + string.replaceFirstChar { it.uppercase() } + } + } + + private fun String.getStringWithoutSpace(): String { + return this.replace(SPACE_SEPARATOR, "") + } } NewProject.generate(args) From 11b9f490cdbab22dca8b5b4ceb97518007d8dffd Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Sat, 9 Jul 2022 16:36:00 +0700 Subject: [PATCH 2/9] [#240] Remove sample code --- .../coroutine/di/modules/RepositoryModule.kt | 7 +- .../co/nimblehq/coroutine/model/UiModel.kt | 11 +++ .../nimblehq/coroutine/model/UserUiModel.kt | 17 ----- .../co/nimblehq/coroutine/ui/ErrorMapping.kt | 1 - .../coroutine/ui/base/BaseFragment.kt | 2 + .../coroutine/ui/base/NavigationEvent.kt | 7 +- .../coroutine/ui/screens/MainNavigator.kt | 22 ------ .../coroutine/ui/screens/MainViewModel.kt | 4 +- .../ui/screens/compose/ComposeFragment.kt | 33 --------- .../ui/screens/compose/ComposeViewModel.kt | 57 --------------- .../ui/screens/compose/HomeComposeFragment.kt | 36 ++++++++++ .../screens/compose/HomeComposeViewModel.kt | 38 ++++++++++ .../compose/composables/ComposeScreen.kt | 46 ------------- .../compose/composables/ContentCard.kt | 26 ------- .../screens/compose/composables/HomeScreen.kt | 32 +++++++++ .../screens/compose/composables/TitleBar.kt | 54 --------------- .../screens/compose/composables/UserItem.kt | 53 -------------- .../screens/compose/composables/UserList.kt | 28 -------- .../ui/screens/compose/theme/Color.kt | 4 +- .../ui/screens/compose/theme/Dimension.kt | 7 +- .../ui/screens/compose/theme/Shape.kt | 10 --- .../ui/screens/compose/theme/Theme.kt | 18 ++--- .../ui/screens/compose/theme/Typography.kt | 16 ----- .../coroutine/ui/screens/home/HomeFragment.kt | 65 ------------------ .../ui/screens/home/HomeViewModel.kt | 63 ----------------- .../ui/screens/second/SecondBundle.kt | 9 --- .../ui/screens/second/SecondFragment.kt | 28 -------- .../ui/screens/second/SecondViewModel.kt | 9 --- .../coroutine/ui/screens/xml/HomeFragment.kt | 36 ++++++++++ .../coroutine/ui/screens/xml/HomeViewModel.kt | 38 ++++++++++ .../src/main/res/font/montserrat_regular.ttf | Bin 245708 -> 0 bytes .../app/src/main/res/layout/fragment_home.xml | 26 ++----- .../src/main/res/layout/fragment_second.xml | 20 ------ .../app/src/main/res/layout/view_loading.xml | 20 ------ .../main/res/navigation/nav_graph_main.xml | 35 ++-------- .../app/src/main/res/values/colors.xml | 6 +- .../src/main/res/values/colors_pallete.xml | 7 -- .../app/src/main/res/values/dimens.xml | 4 ++ .../app/src/main/res/values/strings.xml | 2 +- .../app/src/main/res/values/styles.xml | 11 ++- .../app/src/staging/res/values/strings.xml | 1 + .../screens/{home => xml}/HomeFragmentTest.kt | 8 +-- .../data/repository/RepositoryImpl.kt | 15 ++++ .../data/repository/UserRepositoryImpl.kt | 15 ---- .../coroutine/data/response/Response.kt | 12 ++++ .../coroutine/data/response/UserResponse.kt | 62 ----------------- .../coroutine/data/service/ApiService.kt | 4 +- .../data/repository/RepositoryTest.kt | 44 ++++++++++++ .../data/repository/UserRepositoryTest.kt | 53 -------------- .../nimblehq/coroutine/domain/model/Model.kt | 5 ++ .../nimblehq/coroutine/domain/model/User.kt | 26 ------- .../coroutine/domain/repository/Repository.kt | 8 +++ .../domain/repository/UserRepository.kt | 8 --- .../domain/usecase/GetUsersUseCase.kt | 17 ----- .../coroutine/domain/usecase/UseCase.kt | 17 +++++ .../domain/usecase/GetUsersUseCaseTest.kt | 54 --------------- .../coroutine/domain/usecase/UseCaseTest.kt | 46 +++++++++++++ CoroutineTemplate/settings.gradle.kts | 1 - 58 files changed, 385 insertions(+), 919 deletions(-) create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UserUiModel.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeFragment.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeViewModel.kt create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ComposeScreen.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ContentCard.kt create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/TitleBar.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserItem.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserList.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Shape.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Typography.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeFragment.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeViewModel.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondBundle.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondFragment.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondViewModel.kt create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt delete mode 100755 CoroutineTemplate/app/src/main/res/font/montserrat_regular.ttf delete mode 100644 CoroutineTemplate/app/src/main/res/layout/fragment_second.xml delete mode 100644 CoroutineTemplate/app/src/main/res/layout/view_loading.xml delete mode 100644 CoroutineTemplate/app/src/main/res/values/colors_pallete.xml create mode 100644 CoroutineTemplate/app/src/main/res/values/dimens.xml rename CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/{home => xml}/HomeFragmentTest.kt (80%) create mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt delete mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/UserRepositoryImpl.kt create mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt delete mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/UserResponse.kt create mode 100644 CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt delete mode 100644 CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/UserRepositoryTest.kt create mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt delete mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/User.kt create mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt delete mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/UserRepository.kt delete mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCase.kt create mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt delete mode 100644 CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCaseTest.kt create mode 100644 CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt index ac8f63742..03dff62d0 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt @@ -1,8 +1,8 @@ package co.nimblehq.coroutine.di.modules -import co.nimblehq.coroutine.data.repository.UserRepositoryImpl +import co.nimblehq.coroutine.data.repository.RepositoryImpl import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.repository.UserRepository +import co.nimblehq.coroutine.domain.repository.Repository import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -13,6 +13,5 @@ import dagger.hilt.android.components.ViewModelComponent class RepositoryModule { @Provides - fun provideUserRepository(apiService: ApiService): UserRepository = - UserRepositoryImpl(apiService) + fun provideRepository(apiService: ApiService): Repository = RepositoryImpl(apiService) } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt new file mode 100644 index 000000000..71985dffd --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt @@ -0,0 +1,11 @@ +package co.nimblehq.coroutine.model + +import co.nimblehq.coroutine.domain.model.Model + +data class UiModel( + val id: Int +) + +private fun Model.toUiModel() = UiModel(id = id ?: -1) + +fun List.toUiModels() = this.map { it.toUiModel() } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UserUiModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UserUiModel.kt deleted file mode 100644 index f95491aa7..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UserUiModel.kt +++ /dev/null @@ -1,17 +0,0 @@ -package co.nimblehq.coroutine.model - -import co.nimblehq.coroutine.domain.model.User - -data class UserUiModel( - val id: Int, - val name: String, - val username: String, - val phone: String -) - -private fun User.toUserUiModel(): UserUiModel = - UserUiModel(id = id ?: 0, name = name, username = username, phone = phone) - -fun List.toUserUiModels(): List { - return this.map { it.toUserUiModel() } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt index 38f1980fc..65abdc5f2 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt @@ -4,6 +4,5 @@ import android.content.Context import co.nimblehq.coroutine.R fun Throwable.userReadableMessage(context: Context): String { - // TODO implement user readable message return context.getString(R.string.error_generic) } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt index d28bc846d..9566f4817 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt @@ -39,6 +39,8 @@ abstract class BaseFragment : Fragment(), BaseFragmentCallback override fun initViewModel() {} + override fun setupView() {} + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt index 2f9a4014b..0b246cd23 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt @@ -1,8 +1,3 @@ package co.nimblehq.coroutine.ui.base -import co.nimblehq.coroutine.ui.screens.second.SecondBundle - -sealed class NavigationEvent { - data class Second(val bundle: SecondBundle) : NavigationEvent() - object Compose : NavigationEvent() -} +sealed class NavigationEvent diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt index a5b81e307..88816e8b6 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt @@ -5,8 +5,6 @@ import co.nimblehq.coroutine.R import co.nimblehq.coroutine.ui.base.BaseNavigator import co.nimblehq.coroutine.ui.base.BaseNavigatorImpl import co.nimblehq.coroutine.ui.base.NavigationEvent -import co.nimblehq.coroutine.ui.screens.home.HomeFragmentDirections -import co.nimblehq.coroutine.ui.screens.second.SecondBundle import javax.inject.Inject interface MainNavigator : BaseNavigator @@ -18,28 +16,8 @@ class MainNavigatorImpl @Inject constructor( override val navHostFragmentId = R.id.navHostFragment override fun navigate(event: NavigationEvent) { - when (event) { - is NavigationEvent.Second -> navigateToSecond(event.bundle) - is NavigationEvent.Compose -> navigateToCompose() - } - } - - private fun navigateToSecond(bundle: SecondBundle) { - val navController = findNavController() - when (navController?.currentDestination?.id) { - R.id.homeFragment -> navController.navigate( - HomeFragmentDirections.actionHomeFragmentToSecondFragment(bundle) - ) - else -> unsupportedNavigation() - } - } - - private fun navigateToCompose() { val navController = findNavController() when (navController?.currentDestination?.id) { - R.id.homeFragment -> navController.navigate( - HomeFragmentDirections.actionHomeFragmentToComposeFragment() - ) else -> unsupportedNavigation() } } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt index 5d5ac7f0b..e7e87a06f 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt @@ -6,4 +6,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel -class MainViewModel @Inject constructor(dispatchers: DispatchersProvider) : BaseViewModel(dispatchers) +class MainViewModel @Inject constructor( + dispatchers: DispatchersProvider +) : BaseViewModel(dispatchers) diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeFragment.kt deleted file mode 100644 index 10c287b9e..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeFragment.kt +++ /dev/null @@ -1,33 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.ui.ExperimentalComposeUiApi -import androidx.fragment.app.viewModels -import co.nimblehq.coroutine.ui.base.BaseComposeFragment -import co.nimblehq.coroutine.ui.screens.compose.composables.ComposeScreen -import dagger.hilt.android.AndroidEntryPoint - -@ExperimentalComposeUiApi -@AndroidEntryPoint -class ComposeFragment : BaseComposeFragment() { - - private val viewModel: ComposeViewModel by viewModels() - - override val composeScreen: @Composable () -> Unit - get() = { - with(viewModel) { - ComposeScreen( - userUiModels = userUiModels.collectAsState().value, - showLoading = showLoading.collectAsState().value, - textFieldValue = textFieldValue.value, - onTextFieldValueChange = ::updateTextFieldValue, - onUserItemClick = toaster::display - ) - } - } - - override fun bindViewModel() { - viewModel.error bindTo toaster::display - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeViewModel.kt deleted file mode 100644 index 3b94cba88..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/ComposeViewModel.kt +++ /dev/null @@ -1,57 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose - -import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.model.toUserUiModels -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.domain.usecase.GetUsersUseCase -import co.nimblehq.coroutine.domain.usecase.UseCaseResult -import co.nimblehq.coroutine.util.DispatchersProvider -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import javax.inject.Inject - -interface Output { - - val userUiModels: StateFlow> - - val textFieldValue: State - - fun updateTextFieldValue(value: String) -} - -@HiltViewModel -class ComposeViewModel @Inject constructor( - private val getUsersUseCase: GetUsersUseCase, - dispatchers: DispatchersProvider -) : BaseViewModel(dispatchers), Output { - - private val _userUiModels = MutableStateFlow>(emptyList()) - override val userUiModels: StateFlow> - get() = _userUiModels - - private val _textFieldValue = mutableStateOf("") - override val textFieldValue: State - get() = _textFieldValue - - init { - fetchUsers() - } - - override fun updateTextFieldValue(value: String) { - _textFieldValue.value = value - } - - private fun fetchUsers() { - showLoading() - execute { - when (val result = getUsersUseCase.execute()) { - is UseCaseResult.Success -> _userUiModels.value = result.data.toUserUiModels() - is UseCaseResult.Error -> _error.emit(result.exception.message.orEmpty()) - } - hideLoading() - } - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt new file mode 100644 index 000000000..de53e370d --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt @@ -0,0 +1,36 @@ +package co.nimblehq.coroutine.ui.screens.compose + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.res.stringResource +import co.nimblehq.coroutine.R +import co.nimblehq.coroutine.extension.provideViewModels +import co.nimblehq.coroutine.ui.base.BaseComposeFragment +import co.nimblehq.coroutine.ui.screens.MainNavigator +import co.nimblehq.coroutine.ui.screens.compose.composables.HomeScreen +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject + +@ExperimentalComposeUiApi +@AndroidEntryPoint +class HomeComposeFragment : BaseComposeFragment() { + + @Inject + lateinit var navigator: MainNavigator + + private val viewModel: HomeComposeViewModel by provideViewModels() + + override val composeScreen: @Composable () -> Unit + get() = { + HomeScreen( + title = stringResource(id = R.string.app_name), + uiModels = viewModel.uiModels.collectAsState().value + ) + } + + override fun bindViewModel() { + viewModel.error bindTo toaster::display + viewModel.navigator bindTo navigator::navigate + } +} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt new file mode 100644 index 000000000..d5fcc3fc2 --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt @@ -0,0 +1,38 @@ +package co.nimblehq.coroutine.ui.screens.compose + +import co.nimblehq.coroutine.domain.usecase.UseCase +import co.nimblehq.coroutine.domain.usecase.UseCaseResult +import co.nimblehq.coroutine.model.UiModel +import co.nimblehq.coroutine.model.toUiModels +import co.nimblehq.coroutine.ui.base.BaseViewModel +import co.nimblehq.coroutine.util.DispatchersProvider +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +@HiltViewModel +class HomeComposeViewModel @Inject constructor( + private val useCase: UseCase, + dispatchers: DispatchersProvider +) : BaseViewModel(dispatchers) { + + private val _uiModels = MutableStateFlow>(emptyList()) + val uiModels: StateFlow> + get() = _uiModels + + init { + execute { + when (val result = useCase.execute()) { + is UseCaseResult.Success -> { + val uiModels = result.data.toUiModels() + _uiModels.emit(uiModels) + } + is UseCaseResult.Error -> { + val errorMessage = result.exception.message.orEmpty() + _error.emit(errorMessage) + } + } + } + } +} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ComposeScreen.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ComposeScreen.kt deleted file mode 100644 index 6dcb10337..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ComposeScreen.kt +++ /dev/null @@ -1,46 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables - -import androidx.compose.foundation.layout.Box -import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.ui.* -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.ui.screens.compose.theme.ComposeTheme - -@Suppress("LongMethod", "LongParameterList") -@ExperimentalComposeUiApi -@Composable -fun ComposeScreen( - userUiModels: List, - showLoading: Boolean, - textFieldValue: String, - onTextFieldValueChange: (String) -> Unit, - onUserItemClick: (String) -> Unit -) { - ComposeTheme { - Scaffold( - topBar = { - TitleBar( - title = "Jetpack Compose", - textFieldValue = textFieldValue, - onTextFieldValueChange = onTextFieldValueChange - ) - } - ) { - ContentCard { - Box { - UserList( - userUiModels = userUiModels, - onUserItemClick = onUserItemClick - ) - if (showLoading) { - CircularProgressIndicator( - modifier = Modifier.align(alignment = Alignment.Center) - ) - } - } - } - } - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ContentCard.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ContentCard.kt deleted file mode 100644 index 821127995..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/ContentCard.kt +++ /dev/null @@ -1,26 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables - -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Card -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension - -@Composable -fun ContentCard( - content: @Composable () -> Unit -) { - Card( - shape = RoundedCornerShape( - topStart = Dimension.Dp24, - topEnd = Dimension.Dp24, - bottomStart = Dimension.Dp0, - bottomEnd = Dimension.Dp0 - ), - elevation = Dimension.Dp0, - modifier = Modifier.fillMaxSize() - ) { - content.invoke() - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt new file mode 100644 index 000000000..5aebb74ef --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt @@ -0,0 +1,32 @@ +package co.nimblehq.coroutine.ui.screens.compose.composables + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import co.nimblehq.coroutine.model.UiModel +import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension.spacingNormal +import co.nimblehq.coroutine.ui.screens.compose.theme.Theme +import timber.log.Timber + +@Suppress("FunctionNaming") +@ExperimentalComposeUiApi +@Composable +fun HomeScreen( + title: String, + uiModels: List +) { + Theme { + Text( + text = title, + textAlign = TextAlign.Center, + modifier = Modifier + .wrapContentHeight() + .padding(all = spacingNormal) + ) + } + Timber.d("Result : $uiModels") +} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/TitleBar.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/TitleBar.kt deleted file mode 100644 index 2f84dfbe5..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/TitleBar.kt +++ /dev/null @@ -1,54 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.runtime.Composable -import androidx.compose.ui.ExperimentalComposeUiApi -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension - -@Suppress("LongMethod") -@ExperimentalComposeUiApi -@Composable -fun TitleBar( - title: String, - textFieldValue: String, - onTextFieldValueChange: (String) -> Unit -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(Dimension.Dp24) - ) { - val keyboardController = LocalSoftwareKeyboardController.current - - Text( - text = title, - style = MaterialTheme.typography.h6 - ) - TextField( - value = textFieldValue, - onValueChange = onTextFieldValueChange, - label = { Text(text = "Demo TextField") }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Text, - imeAction = ImeAction.Done, - ), - keyboardActions = KeyboardActions( - onDone = { keyboardController?.hide() }, - ), - modifier = Modifier - .fillMaxWidth() - .padding(top = Dimension.Dp16) - ) - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserItem.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserItem.kt deleted file mode 100644 index ac799200f..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserItem.kt +++ /dev/null @@ -1,53 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables - -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import co.nimblehq.coroutine.R -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension - -@Suppress("LongMethod") -@Composable -fun UserItem( - userUiModel: UserUiModel, - onClick: (String) -> Unit -) { - Surface( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = { onClick(userUiModel.toString()) }) - ) { - Row(modifier = Modifier.padding(Dimension.Dp16)) { - Image( - painter = painterResource(id = R.drawable.ic_launcher_foreground), - contentDescription = null, - modifier = Modifier - .width(Dimension.Dp52) - .height(Dimension.Dp52), - ) - Column( - modifier = Modifier - .align(Alignment.CenterVertically) - .padding(start = Dimension.Dp16) - ) { - with(userUiModel) { - Text( - text = name, - style = MaterialTheme.typography.subtitle1 - ) - Text( - text = phone, - style = MaterialTheme.typography.body1, - modifier = Modifier.padding(top = Dimension.Dp4) - ) - } - } - } - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserList.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserList.kt deleted file mode 100644 index 8c3ea9ed3..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/UserList.kt +++ /dev/null @@ -1,28 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables - -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.Divider -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension - -@Composable -fun UserList( - userUiModels: List, - onUserItemClick: (String) -> Unit -) { - LazyColumn { - itemsIndexed(items = userUiModels) { index, user -> - if (index == 0) Spacer(modifier = Modifier.height(Dimension.Dp8)) - UserItem( - userUiModel = user, - onClick = onUserItemClick - ) - if (index != userUiModels.size - 1) Divider() - } - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt index 7b22814a3..63f5f90bc 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt @@ -4,6 +4,6 @@ import androidx.compose.ui.graphics.Color @Suppress("MagicNumber") object Color { - val BlueFreeSpeech = Color(0xFF3F51B5) - val AlmostWhite = Color(0xFFDFE4EA) + val GreenCitrus = Color(0xFF99CC00) + val GreenChristi = Color(0xFF669900) } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt index 6389f8a20..09bc9461a 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt @@ -4,10 +4,5 @@ import androidx.compose.ui.unit.dp @Suppress("MagicNumber") object Dimension { - val Dp0 = 0.dp - val Dp4 = 4.dp - val Dp8 = 8.dp - val Dp16 = 16.dp - val Dp24 = 24.dp - val Dp52 = 52.dp + val spacingNormal = 16.dp } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Shape.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Shape.kt deleted file mode 100644 index 8feb9f53b..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Shape.kt +++ /dev/null @@ -1,10 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.theme - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Shapes - -object Shape { - val ComposeShapes = Shapes( - medium = RoundedCornerShape(Dimension.Dp8) - ) -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt index d34922a73..323ac237a 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt @@ -4,21 +4,17 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.lightColors import androidx.compose.runtime.Composable -object Palette { - val ComposeLightPalette = lightColors( - primary = Color.BlueFreeSpeech, - background = Color.AlmostWhite - ) -} - +@Suppress("FunctionNaming") @Composable -fun ComposeTheme( +fun Theme( content: @Composable () -> Unit ) { MaterialTheme( - colors = Palette.ComposeLightPalette, - typography = Typography.ComposeTypography, - shapes = Shape.ComposeShapes, + colors = lightColors( + primary = Color.GreenCitrus, + primaryVariant = Color.GreenChristi, + secondary = Color.GreenCitrus + ), content = content ) } diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Typography.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Typography.kt deleted file mode 100644 index 9e8ad213e..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Typography.kt +++ /dev/null @@ -1,16 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.compose.theme - -import androidx.compose.material.Typography -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import co.nimblehq.coroutine.R - -object Typography { - private val MontserratFontFamily = FontFamily( - Font(R.font.montserrat_regular) - ) - - val ComposeTypography = Typography( - defaultFontFamily = MontserratFontFamily - ) -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeFragment.kt deleted file mode 100644 index 5d78f933c..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeFragment.kt +++ /dev/null @@ -1,65 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.home - -import android.view.LayoutInflater -import android.view.ViewGroup -import co.nimblehq.common.extensions.visibleOrGone -import co.nimblehq.coroutine.databinding.FragmentHomeBinding -import co.nimblehq.coroutine.databinding.ViewLoadingBinding -import co.nimblehq.coroutine.extension.provideViewModels -import co.nimblehq.coroutine.lib.IsLoading -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.ui.base.BaseFragment -import co.nimblehq.coroutine.ui.screens.MainNavigator -import co.nimblehq.coroutine.ui.screens.second.SecondBundle -import dagger.hilt.android.AndroidEntryPoint -import timber.log.Timber -import javax.inject.Inject - -@AndroidEntryPoint -class HomeFragment : BaseFragment() { - - @Inject - lateinit var navigator: MainNavigator - - private val viewModel: HomeViewModel by provideViewModels() - - private lateinit var viewLoadingBinding: ViewLoadingBinding - - override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHomeBinding - get() = { inflater, container, attachToParent -> - FragmentHomeBinding.inflate(inflater, container, attachToParent) - } - - override fun setupView() { - viewLoadingBinding = ViewLoadingBinding.bind(binding.root) - } - - override fun bindViewEvents() { - super.bindViewEvents() - - with(binding) { - btNext.setOnClickListener { - viewModel.navigateToSecond(SecondBundle("From home")) - } - - btCompose.setOnClickListener { - viewModel.navigateToCompose() - } - } - } - - override fun bindViewModel() { - viewModel.userUiModels bindTo ::displayUsers - viewModel.showLoading bindTo ::bindLoading - viewModel.error bindTo toaster::display - viewModel.navigator bindTo navigator::navigate - } - - private fun displayUsers(userUiModels: List) { - Timber.d("Result : $userUiModels") - } - - private fun bindLoading(isLoading: IsLoading) { - viewLoadingBinding.pbLoading.visibleOrGone(isLoading) - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeViewModel.kt deleted file mode 100644 index 038711054..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/home/HomeViewModel.kt +++ /dev/null @@ -1,63 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.home - -import androidx.lifecycle.viewModelScope -import co.nimblehq.coroutine.model.UserUiModel -import co.nimblehq.coroutine.model.toUserUiModels -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.ui.base.NavigationEvent -import co.nimblehq.coroutine.ui.screens.second.SecondBundle -import co.nimblehq.coroutine.domain.usecase.GetUsersUseCase -import co.nimblehq.coroutine.domain.usecase.UseCaseResult -import co.nimblehq.coroutine.util.DispatchersProvider -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - -interface Output { - - val userUiModels: StateFlow> - - fun navigateToSecond(bundle: SecondBundle) - - fun navigateToCompose() -} - -@HiltViewModel -class HomeViewModel @Inject constructor( - private val getUsersUseCase: GetUsersUseCase, - dispatchers: DispatchersProvider -) : BaseViewModel(dispatchers), Output { - - private val _userUiModels = MutableStateFlow>(emptyList()) - override val userUiModels: StateFlow> - get() = _userUiModels - - init { - fetchUsers() - } - - override fun navigateToSecond(bundle: SecondBundle) { - viewModelScope.launch { - _navigator.emit(NavigationEvent.Second(bundle)) - } - } - - override fun navigateToCompose() { - viewModelScope.launch { - _navigator.emit(NavigationEvent.Compose) - } - } - - private fun fetchUsers() { - showLoading() - execute { - when (val result = getUsersUseCase.execute()) { - is UseCaseResult.Success -> _userUiModels.value = result.data.toUserUiModels() - is UseCaseResult.Error -> _error.emit(result.exception.message.orEmpty()) - } - hideLoading() - } - } -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondBundle.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondBundle.kt deleted file mode 100644 index e94381569..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondBundle.kt +++ /dev/null @@ -1,9 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.second - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize -data class SecondBundle( - val message: String -) : Parcelable diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondFragment.kt deleted file mode 100644 index 34c082881..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondFragment.kt +++ /dev/null @@ -1,28 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.second - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.fragment.app.viewModels -import androidx.navigation.fragment.navArgs -import co.nimblehq.coroutine.databinding.FragmentSecondBinding -import co.nimblehq.coroutine.ui.base.BaseFragment -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class SecondFragment : BaseFragment() { - - private val viewModel by viewModels() - - private val args: SecondFragmentArgs by navArgs() - - override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentSecondBinding - get() = { inflater, container, attachToParent -> - FragmentSecondBinding.inflate(inflater, container, attachToParent) - } - - override fun setupView() { - binding.tvMessage.text = args.bundle.message - } - - override fun bindViewModel() {} -} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondViewModel.kt deleted file mode 100644 index b790f1d5d..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/second/SecondViewModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package co.nimblehq.coroutine.ui.screens.second - -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.util.DispatchersProvider -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject - -@HiltViewModel -class SecondViewModel @Inject constructor(dispatchers: DispatchersProvider) : BaseViewModel(dispatchers) diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt new file mode 100644 index 000000000..85116dac8 --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt @@ -0,0 +1,36 @@ +package co.nimblehq.coroutine.ui.screens.xml + +import android.view.LayoutInflater +import android.view.ViewGroup +import co.nimblehq.coroutine.databinding.FragmentHomeBinding +import co.nimblehq.coroutine.extension.provideViewModels +import co.nimblehq.coroutine.model.UiModel +import co.nimblehq.coroutine.ui.base.BaseFragment +import co.nimblehq.coroutine.ui.screens.MainNavigator +import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber +import javax.inject.Inject + +@AndroidEntryPoint +class HomeFragment : BaseFragment() { + + @Inject + lateinit var navigator: MainNavigator + + private val viewModel: HomeViewModel by provideViewModels() + + override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHomeBinding + get() = { inflater, container, attachToParent -> + FragmentHomeBinding.inflate(inflater, container, attachToParent) + } + + override fun bindViewModel() { + viewModel.uiModels bindTo ::displayUiModels + viewModel.error bindTo toaster::display + viewModel.navigator bindTo navigator::navigate + } + + private fun displayUiModels(uiModels: List) { + Timber.d("Result : $uiModels") + } +} diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt new file mode 100644 index 000000000..1009f1e30 --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt @@ -0,0 +1,38 @@ +package co.nimblehq.coroutine.ui.screens.xml + +import co.nimblehq.coroutine.domain.usecase.UseCase +import co.nimblehq.coroutine.domain.usecase.UseCaseResult +import co.nimblehq.coroutine.model.UiModel +import co.nimblehq.coroutine.model.toUiModels +import co.nimblehq.coroutine.ui.base.BaseViewModel +import co.nimblehq.coroutine.util.DispatchersProvider +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +@HiltViewModel +class HomeViewModel @Inject constructor( + private val useCase: UseCase, + dispatchers: DispatchersProvider +) : BaseViewModel(dispatchers) { + + private val _uiModels = MutableStateFlow>(emptyList()) + val uiModels: StateFlow> + get() = _uiModels + + init { + execute { + when (val result = useCase.execute()) { + is UseCaseResult.Success -> { + val uiModels = result.data.toUiModels() + _uiModels.emit(uiModels) + } + is UseCaseResult.Error -> { + val errorMessage = result.exception.message.orEmpty() + _error.emit(errorMessage) + } + } + } + } +} diff --git a/CoroutineTemplate/app/src/main/res/font/montserrat_regular.ttf b/CoroutineTemplate/app/src/main/res/font/montserrat_regular.ttf deleted file mode 100755 index 8d443d5d56ac36091e9689cd5d1b1948d9124545..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245708 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 z z?MhR7|BmJh^y@$V@q6bVOG&A6kT2B$(ag2LZHi(#YGQvck8YHfSE5w5ENbTg8QY{u z@gaa=t_8k-<-mN!{fFp9J25-cT%S3}GnFghAPa*GQ`Z-bR>ty-A~moH+W*lhS`cG2 z;~r6fRI~%$i{QZl>>k^c{+nw6aUq#0N&WCY`d|jePAEnjvT0ZgebC3~M`Y=+l}DHF z;aUwuT&L*kw3^?7-oF`?n3lg4{@+Xw_A}%%cAQOYtFTmpcBBh9>8Jc(ew$IQW2^a> znVNC!UxK6}xlN_K)fPmFW&9az>mJ)9x9WqhbJ6d^^pvwR@#D~}=natGQEx{Dl_$WC+iL-_ut zkiWQ66yR>-0eB8{i|~xQ^Nf;Ix*hesFWzh9lKf-;GSJi><6pGT)1(6uE@nbxg+2%Ru!T* z?zC+bd(nNiBHLOpE>sIe2JWmqQVfIz<1u(1tBw_#?yg1n3F-udoTyHOdxcto@Uzre zVi4}GJsaWY!=}+y7pMymev!HeFu21O?n~4qaFdneK-^|~nTWv3@d|`otFA>XZm~u9 zP3k7NahI*g#BH{>Aof;uD?;vu4P*vxuzeWTjE}0v0QtCj93juB=iq)py#zPzti|&U z^@bSEwvhvIckSEAWtCcmR3EAj0f}2{@mvEt$#JlgTnoqzY6ILG)kfjby|rQlZm!(~ zm~Yj$Viaz${SLX473C=0V*7(oxX1QKK;kZ2r20ku0?favUttY`Y84~EYz2!Ee8ec+ zYwN*c1Xn~NBtxU6!Rj(kRN`*ie6hXmrh6jY;cJ)5Gu_u7``!xbb!bAWL)5241FT{lU?J-OcVZpjzN`b>k#&G$SqC_P zb$~I}0amaMaDUbT*0T<9Z`J`8u@10~b%3?3102gbz#*&yjIj=ISKMv8GjyqBUzEez z-ZIt%mW1q!s#z0QvyFX`(f0OWO<)OY0*A6Da2RU>b6Dp)i8X;kSrfPq>j3v*?cW5} z{!L)*-xSvVm9h4ZZoZu?%2@jsXYF4ZYyaXQi=*zW{o9?jf8AO8x4X4CB5m&^*7i3!TWR!#gUL*8BDM-uB)` z2x;+q;Evi4#6Z^mb;tZlQpon|Vx3j|O7%ArZk_t#f(a)db#^bzvbVFmI8|j~ew*u@ zlJ>pRNqv8Fw)v`<931|-XUU6XjeC&^Gr+ zJH)ZjXcZ@;rg8T%?mfO3_4$ss3YKQl8<_mfD~E&@f&JY;SluqRBMo`D^fsv2dFGS4F=S9h}{k`eGxNQxWL-q`3ApDSi33JBqm~xpNMf~ zB5V;6kC4F#8H^C)>knUl`1*6&dZevK+Ir^J%iz|_kiI^IjP*74kF(|8Ldr4tjm2*q ze&g}m2fqpU?Tg?0_pcnGpmgzrZc#!5D52xT zKSQ!4dYgn^M`A?-=`RaXUzUVbtSrSZhF=+e<@iORk>k7z9)BVxq85gs6vv?yBTIpyWlq-zkTqVfZt^NrsB81=mOi*ELfg)f!%4AHw$4+_+5zKMfhEe z-_`hCgWpZb&FGI^gxvlN%CX;718zY6hhaVTI;>#wu*#?ZCcK07+Xq-_zn%Odc^#}e zzk;^-187mM!}^*uhOqs|8v9%5idGRMF!aYt@dw&hK$^A5gxCrHROrF0^*0c@7VG!t z0P{2SP;a1qb@E=$>1VMULcRywdaOJ*VIBA*@Moe0qiOw5e~^dS2@#-`R-j~~^*MIF zw_3}o&pXR8iP}&9_$yS_BCuWYpaB|n zt3P9H2kXRAgm!RkqeAgb z5qm4FcX$qE%tHO5hM{2~tB0*bC)y>fS?M1dC!0-v4m`zLy(ntd{>77Y`O?hlZENRe5clKX>{8j^O zKTuiy4|)hN8qBamA__>?51R2Ho2g$oUzCG&Ues6Z2Wf~p;>jk8!xM2F_C0#?_vE*D zzsKH8kj^AGxssbjtq7}h&QmnXXuT@nfwr(crW=BDEO3je^;XftCMe{r_ev(K18XoJIp=wOFS{+pvKo=mf0w>sn+4& z0zd4SkbXUIQ%hLO{p@u>z6boTGZ)bJ81|jyL%>cYUIVU~y{c8fLDsma6@-(WIDg1* zAdJ7WXKHLq#hU(>@^|LiCY>2UwizF{fg@ywKBEin4Eg_17|M=OAoU54R5T8z$EM)^ z6IU45e*~XK$$ygKkHDDz{rf3+=18lX&PIgaPj6#>r^Y(1@_3BdPtCVzXLA9>+pzbT9YPt`e5v(`D(TCb^0U;`VoA;gN5dnkMa7mWD#i0v>N zqTD>bV)q}go5Wry-5OxZfz=3&i)-QbM@GtteEz>!4JsbP*xBjMqXGJ3&p+0Z0-1>F z@pngzKZf&<(ffPQ-0t{4*QgDuX=*R4xxJZLjP^SN{)PH0{xgjf1QVJe(5lF4f@Wco zhm6cZvpY*};DT*eJjarBK$bK1L)h#dw8@!cQv0p8?L%7S1lDH5CZ1^C!1n{Su{lo6^V4Eh&ow+jUuEf<%YpS0Y*GADqx~WF z6~y4*71XbS)E|=@`3B{K?{)OZ*U{#GX7145<+m6mh*O3h(@V{hR+rch4)CF`kQ-rS zpAy1qAP|l|>W8CbwuF9qNM!s8)gYZ~K%bzmvkwohm2fDzQ9{H}|MNd20sYHQxONHa zzXbl5k!Y2)#^DlLiP>1pP&v`}QQn_z`+#;QR3fI)uW!I{8%J%^cubZsgpqcQsg=_| zW=N)_F~xF^;Q7lf(vX;Hktve>{+$Z>qb^WE5+>0{d?s5*?uD$OKo3e@fSAD;si~LT zko+6djeq!Hw)h6JFv-*3!j29)MbvbEyd$vl?}x9(X!#*Z{55J`A{1IOV2XmH-%{&B z9JNv!n~4w9e^+7Vco1_2%?{sVqW+79{tCP=zN2~Gu zgl8w}lhm(iOkiq39c%?n0T4!Y6nvQTZv|dj1w4pyuQk1tuu>e)VHU_wZDMR-+P?}+ z9|hO(47^-Kk)4Ab5LyTxZAh<_#|^+fxF2AX>a zkL_@$a|7dP>XTZhQW(~1!Dwb+s3(U;OkgH_{G|3Aj5IbZ7+VblT5tdXXftXCA=~5? zO8xIgqHxL41}N=zVltj+1xOu18#Q0jwAfMGgpi-UWa9@o(&=o5E62i7deY@l8e0Dk zvv^2**a1_xbQA|p6W##Ix}*sOKB5l!@W(@_-x}&|82)TxT#(Rc1^E@QnelNQmv<-h zsINftGg#&KOTLEwzB+kt@^a+!A+LbfK{opY?fWN;4bLUtM~?$n&>sclwBG260x4Ia zRCGGTZ_xITzJM$uF?Qp(g<1nJfhy$v8Gi4hU#~-N{1UOW%6|@a%kP4=SMdH3~>}Twjf`bQQit``h@vjJ#+yLl$jsA!H5e{Y#<_R6T<9Zvf)CLbkaUZ;oCD(>!CV?<`di_DoCdLne^uQ{s$uPIqc}_x%JqbIv&t`_!9YZ}tnmSC9pn zb0zlJXE;~MnR1SE6Rg87c5a77*k#UZ@&WmP^SXRdzUaI`7GchtWN+oXhZE!GI`8Ae zxW&!~>Tq?E^C`}XJH`1?!un~G+>I=o zN2oVAvuJmVY8EB-sd? zqf*%fJEICY2R1}?vPIYH(eh9|K~I$PaWdRNvW={P|0l?+$r40f>z(SI`u~`F6ZopiYyW#s z=bYqZo(@R}Aprf{i$55D(7V>`IK1zh1&4Q?S#5aNo4tnj1JRksMNLNQ zxv10E!v@k9&uV=61bs&;a@b_SE&7g?c#ske@ki-f;2f=Q$~ne4LGX$C);K3QCky@;=L;%-s=g`bU!5}qpQ&$+ zbC&aOg3orYQtwym8#v$9x7fKx-wJFpi=1nn8)fHdmYJnkW|lg4>+4~kS>%{~W|{0W zA5qJ{(szXOsBAS;*lJcfW~*6+t!A}jwwfcIcl1qRvFT#58MvixsjLpl+%jhr)|)Y` zHxpQI=3u>- zyF{>Adlq5sSuSfB&6_M@j&Me}pLb6Ze6lP*Q&@hEv^P^@uxOAq_GT*8o9WbG+gW38 zreM99O3iL_lq_L33fB86SnsD`y`M_WVsn(enTn}*RB(*!C(J6cDmX4UPMG6^6J?`# za_}$0oD!TW*sLXsg3}cBF*o>P@I|K>%Sj*0$ucY_E3up`!g8`II6F97CH0;w)qAc~ z@3~U5r7Xpk(ht@L>(%Dhf{TPVyULW_|8EFmc9prJ0^d~cW>Hy$MP((?BjearRt5hN z{D;PQMeuEvxiYxY$;Z;N%IJmaeoyw6KK7Pn*jrX(Z&_s&M7cKyx2VlqgIfig?PXQ) z!{CQ%;r8HmVMJM!-W~izb8?TYF^jOqtO|Y>+@~J@E4W{|{~bIiyjf;e2AhM;!aNc@ zqV!jaU0H^$W)-%YvEbLiuZ6d0mPJ@>R*FvjRr(R8;HBWtD)}mLFU_8_7<^W1|a~5I4nTri)9yXli*l@boa0b|L#)9p^ z4#f&HOU@LQoJH7h))*aBG%(RYrJ{pM^;If5sMM@6Ym5#m6&+M6I;d21P^svkQqe)B zW))e3C1j1!LBXPfN<{~inyq6ER*p4B2L+1`Dis}6Y8H$&MhBIe1!E1ii#6CQ*2I3I zn3?%T0TnCEEaiM`QEZK^%UMs?G&8)zGAPO^D^v&qtYUp50RIpF*?xJ^lLhlp@Q}iw-dUv?+p^f;F zqEoA}6px8MT_f1+#beN>)zGGe(58jZremQ^F=$g4W1vutSf8)L`g}6h=aaoYuTQyVgFY1-^e$}BXJdojgAMv@ zXxXmVpf_TJ-j5A>qj!t+Sw`6j663_Uql)ug}4LeJ=Lv%dubI%YV&(O?AzRy&Nm{F<7zh6POkI zn4m}zct0DI2Bpq^io-ina7|DncvLW2u-UlR1r3VKyC0VBW3Y5@52go8oSDIX!2wP$ zR`1KPdN080y)QUCSnaG1*2v~+cPRd9D1H)(zo#hvzbN;V;1uP4K@@*A6h9`4|3$%O zB_D&<$D#E}XnhP?pM=)C!Iy*cRPy}be9fw}Nk}HM6ZxvIgv_HQ-8N%+5X@Y!dZfjkSFY z>K}*t=Ry6GSlh>gA7~A5gBydJRMJ)gkCk9GD?w5#!5zZe8es8=e%q@;T@Pwi*ppQu$*SN64{JSG&3cezJy^hcusiEPjP)Q_F^->9 zncoFZX|BwgzmHWR#;UNI^&rN2up)RNc)>Y;Fcq|9fI3u@Yx*d;nHyMX7Y=;|Z_|Pk=@|0aoD&&=?yX8|`%94=@{l0C@w* zAD{<+fG+$2R>hiPO)6vS(5hIoA~?^-H((XM0h93!XpFVSTGgX@2&}?G;Luomtlc>Z zKY>;F3G~FKY4tiLHa#|7t(nh24?Y8p_zcV@5_A=w1FP^H=!xm8Hs{EHV3lG+_p0u$ zv0YWydwAp4g$WRT_z{udDDnXpF6ntro_74`#FCcHw)l z3g3gC*h#WwT&mUgWX+ZNAvEHLFgx~z*car*VcrO<@J2Y4=+*P_Nod3;VKVDtpMcYaR=$6#4oh)iS?@M*J35 z#l8^}SBLk)D!dmOW9Gfk6*KRJM%MnW*mq*zagN4^p(}Px?3y$m&=tEjcCC8+e(d{d z+58zA@n`7ApP>={peuGq><(R*c{TLm)zAmWuo~ZndH6Q$f^WlT@NMYCw_!xgqNeVP zZ^Jx%8(Q&gsKB?O9^Z!D@NF22Z^I0H8>ZpgP#LqRsY~!}n1^q}6nq;h@NH-hVeu>nLw12CZe27!ndIm--b4P8)o6#P>63sExrwH z_%<9!Je$Mua5#{tHfxBc`Z>HEit%x45RR2 z=!4H&jVHq>xV=?ydog?%7Q^$6!-ruRoL>wdhUxe)l*NA?f803?UN9yr`X`*#_%lp` zFO1>OFj3J==7>9V@((F^&Z!RLOiO0@Ls7>gXNN1 zZbsu{(npg&J|UT%Y`&i}7J8T}pL;Nn;o4=Pnk1GeNBp~NB~1+vYLU=0#bH}lJlEwqRr2n!kS&)7X5u-I*t#2 zOb4%$R(gO`)nN3e*01`s{ODu2P_9{{b~BPrAqUDN2j&c_ZRIRR!B6!>y-&Y3!n6iY z*J={;NP26qej%9$45ic=S+(ihOyijzIit4UXeKE?C{cc+BQDHVZZmY5EP)ESq<6j-Eh!H=dP_L^-;57QJK`xo9}g zgNE~=A6bo{W!V`2@lPnd{>R(-dt1o%`_H+KPtw2cPrj%|TILP~vOD#h)s^l?@&>*+ z(#7bR6V7Zv(-cXx#5C~OgISJAzNN=W*nQXiHLc03y5rJS3vU+GM$4j)Xx=quORkUN zNs{APs%P=9di$)d(aE1EDqc*_$e&gIMfLS3>GWiyrI>$MX{o$L%r`puM_q+oNBG|B zJrUl{lo;|6{uiOfZAb<`?OkFNW{qWIv9I2b;mU@%@a@}qekMmV@zZSCG*qg$_X8`T zxt5*0-fo*ydyY-3lOtWXJ^W?Qv*{xTbVHpPGighkC{u)2KP6FRT7(= zOx^I>>>19yC7GNd|9ezlHXwTXJ$q6`ACsD0JDZ?LX}P3FlVnwrl3r)C{K?GXqglUF zTC;fjbnmg0!I~*YcOs=0M(MdW9jsy&hY_S`-`=n2qwBbT!2E}nXfZuU;WfRB^@-@V z{_7rxA1uhEjb^sY9z6YAX}o3^VJk}*VN1o;_kd4UyQQ1~^E|jzrUJ7zv<2F;^5Go_ z%i3u93-y+n20rv(El$#mN)HMTV^qTU7}KEJx?+)h%QdI3YIgILN`9x`7HbsCb@gF- zb)yWXsWf}kQuFTO-OKo2Sc$jP`gUmn(7&b!aj0|XhlcadM+~7?nx|HcwnW!!GxoNq zs@eslmS2OYRMGIw{iKU{+ z`kj8KQ>GKY<_Mna&lTJ&NoEd`%rZ$b7dT0OPk*tK=kM+Bt=xTl#W(er_=;Dm6T&_x z%mI>i=1AIkrg}U}GS5IV&wq0Y{j(+cEJgBJfaJ3X$!9T=&tm^l|5C?8{#hdV=XGl5 zKmD7Wa{p$@Ld%earjUh>Ko(kwEVK$)sEaJL3R$R$nqp1?vd}oP&;+v3Tx6kT$U<|G zh2|g&&6O;)L2)q}gNf4LGzZOsCrK`vk6g3>xoC;xqH~4s4SFSO-8JZQDm2%73A0%8 z(lX?wImk<^H2dcx@wb!QbOIRCd^^ca=XW8mx3k)&DuRp2&~?U|?$c!MQy2HC7-@1B z_okS8)5X0hMw;BkJt#n$+=Vo`7-@1Bb6U)tb}^?@nbWDv=4hnJbi@qN2{s)_Vak!h#E`;-@r28f!c-uI3D2(SK>kvT{G}fGi;v``7RgH(S#}!Img&e= z!id57NL7+ZRq~OlB$29=BUPzHs#1+qr4p%1HByywq$iz7Pr}H+`AAQ~lWOt@Ly#E7jTM(ju=Eaga8Tx2UQ@)Q>tN-Z*!d}Jv3$WZc;o8%)g zagms`ATcRJR^lQnX+l;KASH2;jJQO5ZACs(DG%yLO+FIa8lSKAYFAOgB2jL|pB61P z`?|OETYjLT>$Y;q#!z3|CyF!qU;ikosK#bHU0Va~PpjAe!Doow|Np`WSkW}^;--f5 zHeSDNb!TN8lJ`&jDeFGt$H!|mS2WA8X`Nr7RaKvI;m6v#&!1Vnzktj}`z2B6LELay z^Pik*FY^C`Px~htL!V|!dv)W>^wmyYl17WrH%qgaFD~dly=C`_Q#4!mi8@h={fSdx zr9Vmg=^gtgDf(%Zu{U({P8(0{H0K}782VObe;btf%k(kycLx9W{+D-B`m37Z9Uat! z{33K8?Ng_nkI_jPT*)DzJu#VF!_e9Yij65J~JHy0L?( z!UCcS3y5wkAbPNXn2iNQHx>{*SU_}R0nvj6M3rZe_j<5^=*9w~3JZuHEFeZ=0WlH_ zh;A$(im-r~g9Sth77%4vK$KtsF&7JnDl8z9SU^-^0nv>GL=_eg-B>`(!2)6~77zgz z5Jgx(6v4CR!L3%qr&hzER;PJWvvH_~AFYNH?S&KVg%d4?2Q7sM9R&|s4i8!j7heev zS`80c0}om~AQoRWd}lGdW-YvC{(x9~Bj7tL;5#d@G6=9T7y%DjftA4sEDHkc2vTsR z71$1V#NrFE8W@4qK!DZ22&@Jwuo?($#ztTx5MUipfptKDbwC2^fDu>+1Xux#7!ZrE z0&V{Y_}vP0`y%cOM(ASQuds9eWNO za|PPQ(5~%h0IzpiA#TmtKV~y$4--6-|yc->OH#+b#bl^Q`zkASr&q4d$gZ4X#_PYx0cNu!`9`xQ-XuM0% zc+WxO-Gj!v3@vvRTJ93`+db&FXQSD!LbE**&2|-`0Tb~k$L z9yHihXs~<93HU~|051Q&KG}TEo)m3P!=M0LxXQz2i zWJffE9no}lMBxdZ9qfE&vGZwW=hMZWXFPkJaJSRR4kw=-&S-WxP3&+Q*x|IW!)Zjr ztg|^45v!HG%@j1u?P!=A*x^iLhclBM&S-Wx)7atEp;fM9hcgL%ay|Owdi2SY+4D4^ zNp51d)5Jcfg&odR_BK=5+qAH^8N=RY7c|37>}@8X8E#^4GXc$T%Ya=?3%i#Vb}tp^ zhpX7bRG=SDp&zbdKU2YeW*YmMCiXK;>}Q$=#IG zbGhwaoa-D}2+7*d5tk}$fL2+Zzo`gICe=+!-)o$!d1mAY9~UH9qsnbjjF3|CT+)|F z%C%T~3yV0iT`RJkOdGFvdE#vuLzldNrKrO0Ufd7*9u+ zwYakNtatUSbhWH*wXAEktZVhGYqhLs^{i;MtY6buxq4W+=CX42uyV~~<*H}Rs%N#T zXN8(KAZF||R;XzMR;UJ6s0LQ31|%j8tW6Ccl9EhkZJNW{)XUnmE2~mIt5O52QU$A0 z1FO;~q#+HgO4C`73J0u5IfLTC4vhpG46s=nE(Yv}qrZNVxUXTv*MYHK2gY~(gJQaR z*m-&BXs%)G)@;01FTI*rEY@09je1s%xvUzstQxhf8uhFiio~i|to5uKJ**n_tQvD! zFKSsYYFRI8St;sSDQa0GYFQ)ZvO3IVb*N``=wWrJWp$X#>QKwNP|Lbd&$`gVx-gej zU@ogbEvrB+^uHF$Uk~M<3+1nc^4CN8d!YHX(EPd3{Ca494>Z3PYF`hXuZPahg|^p1 z&ugLQ_0aQL=y@&lydFwk58bYXZr4Mx>j%;5dt&!EyCK7BgksNvV$Voh64}YiyCJ;_ zBcqOndiO!S$3VSjBex1^cqJ06-H=#yAgii_l83fJHBj$yQ14Qx_c*Bc_yP7o78A1F z>4a`~L$N!d*hNt6A}DhWl(`0JR5kRu25D3^RC*lJsAg#OWTa8eQ0&Q2>~UE4RAJXs z1@$h2dY41JYoOjEq24u6?~zdNaY&{nK*J|;hS3z{Q{#|NO+r4^f_!Qc@~M!*kK+uZ zDNy+EB%@*|d;o>7$Hu#u9YqRD?_y$~7PGr3W_M9c)YD?3o`&Zcg{L-mvLe*5BGj-V z)C^b=YFH6!iF7&^X;%T#t}w3YOypc8tPY`UtJ(1iAG6h=sIB-~Xtik~M4j2C+0I*g zZ0)IQMaj={P7w{49#>!UbF@=zJ{^gQ$wI<2fm2!y%y-vw_Cs$a-A-Ckk`T_KJjfeX z>1*cmDBnlZvFP*>`M7SAKg{3%F-eVf=IX=7V0~DRj?+#0zmTBSQOq~%D)i&rS*N;E zyJph@DFT4>>WUzsYaim(y|dcG;FDUlwd1$@tJKcac`7QEkzgSskYv+N#Tfn*&etFt ziQx-=2wRDsDvVxW5&+Y9#wnH0a~4VnLJr|Wl|L0k*kgDtp?uDI|L05UOe3eh?4468 zy`$bbn}I`}xy(YkPwvady>Z6r{o@}`+?jnsZKqxJr}QCa#Y?(sMVeD;aoA)_A#M}R z<=@|_X)XVbkD_x}=}^0?)Z&)ph(EPYEl(XVH1Fd^^iP>3^%>5*#RW-gY1R8Dlxs5X zPne*Qep)=ZEH^a+uZW)fUO1jF_4mB)!FFcm4duKc4|hAq!(vtaQCN%j_nO&q80EEb zq9?a|sHmBrWB}6JKdYz(Ig)^j%E+GQ(E-%vlQgi?GU%*#nw!lqO8KFuY#wnXvW0+j zt*8{%f z{d-x+*}b>e2+ygFq@9thH&Av;!} zFn0c*easr=|HB81jh)j!TTy1oZsfo9eOjmQ#&+DSnY&&d&3&Rdv!us-Tx*ZwVJhe6 zneOch2U^30c+GTr739th&}8UM84!0X)5=c%*Akh|ku1QhnVz>&>U}_KJE=E3+O9AB zgcdHDU-~Z^XIeJXBgo=LoS|=4>mlv8Vw$;0`qzM-!JaYM*%)3q7VR_~nMG{!q`M2B z7R58iQp?K7&WiQgc;`>}QSTw0xAHlRO8?U~MxU^aOfiiWL~0+x&Y{8_UkiTVzH)X5XFte8j#bbKkRt(@^@(+SUGppNNM2gYA4w zb-mBFQ`6p!r_#n>tJpyH@w9S1Av<2#nCgwUn7G@(r;`syJW+|CTBhjsT}0HnOLc$B z7mRE-v7%IaMnCM+r5)Qcdvo+=+m6EQ|JwBbP@O#0rns0!S1jgWm_rpMdcG`Y@JH7$ z7Rq0)r%ucvo{e_QZB#BfcAE`(ZsYpIj zkrJdLDWoEmNJUaeMJkbsl;HW4i)^F-&!=1@Bn3!F;z&qxkdWjdA<0KVl81yO9|=hb z5|T0`Bo#bq#wexLRHQBruGw;>RyCebb zqO@GNPI}^QEZPFemHPyn5Bo@b*t^lH2Kcadr**65!`_XC)uL=%BiL-;0({uJ(Y8)R zzC00aYevd!-s=fu%{k~?bJ4jb(Ya2*d%YX)_13h+*}T`g@m_Dod%YE_x&ZI>$#}1K zz!kaUkrOS;V)eI^>&66^XQHDm!hUcj((n@O z2WKJ^FTs9rCX(?sw6<+%ZA-Bq3@tD#kdLR3kB>liI~^(c6s!nmVu3jgiFpYU^QlP8 zOR&J4g+<{^EHGzbS2z<3%vs3Oi?K1BiB!D=sd_0khM{%kZ1ldNoIRuWHE;B8ywR)i zM(@TOJr{5Ek$9tb#02zHQdg1^*aW3BIm3X6fr_XOQZ}e`w z(W~)B??#I}5iN3nH~L7t(Yps|lw)|Kcc){KWY2iZMXwy7SI!|KNf$op-T0*E;*&lS zpY-nZ*>C2P-i_8d7;pky60LJCTIU!(>6Q4TcjJ>@g-?1n+UQ(-(!23Vuf!+4JFTBK zpY(2g(gU>Ax%i}y#3#KQjdg%e`bhNFx%i}4;*;Ku4m%g0^mcsGtI=l%=(BV1N$U4@-ISA!Njz$ZO1;N-akKIzr? zq<5#a`hc2WUUC4Mm z)9cZQbl{m@hhC%uy+|{9kq-1C&3LBof_9`F?MO4)k@4u%ThNho;F-P)nvxDY)9cWe zbf91FL~GKFXL_hR=|Ia~h-dm(^e7$ZQO4twz6;uv@n}<;(WaE6P3b_JG9GXAdUPrs z_@VEDW~BqoN;7`wyP#hwN53*2KlEMDzPI3kJ{pb7cr-2@_@39Hcj-X;-h%d}1MPdL zgK0(wGaldbdNeT|Xkwc2JrDIUSVIs!$AG^4F=L0jK~k9h++`xbo6>(BsopaE(|b6<-ds2RDouA< z2XC=y0(2P7XsH8q7!%Q9G^4#JKvx~$%iN7Gb9Y)BVXnWp2*$k zr*&Fse#$fu1zkngD4x~c;_BYs@om}8<}3E(E0VqF^lkLf#gYx!X(@_QE{TD8zu5T@ zFKM@GQQ3`$Es+n&JKC?=o**vn(oV)O4_Nb&wbX2K?Q9`@b%*zg9n5*|{MU}ljr+`S z$|29nPAHVfhx?&0wG;03(ba5~KaR!r)k$DrURDbhHPZNWqRJ~zIPzYVWFV=MPbtUr z@PCrbZRb*Vt1{dtlpCS{jUnjZJS zeV#JYcgE}vY`(Mo%Tw9R{BnQXJavA?SvfdZTMKU z;6H2kYI~3{+O>8uDzC`m>DfpkQ7*!l)Z&Q0t+{3&sWxAgq|38sleTOhJ~ty*ra?^!&_Am6p+*$5U@QijRdH*D|p5Di!rgR?$JSWl4P4f~)oUgH5{R-b6i^OT~ zkDarm*%4i^|2xsagm0Rjpn2Twj4s6XzW>-KeA0H_#;5^Vp|9}(#K(e}tI7Nywu0V> zyTa>B``YT69Qfgh^7Pb&^Cs_p^DQJrdSl*SqJyGF*{4a8zy}AmVX*EM)M+UGqkr$X zj@IuAOQrRfk_YK*vJWyf(<6f(imGMl;hW)(Uibec{TV&9XyF>K>c5DVL8lo>5^esj z@2bU@bQNz2O3R?4_R)Q+%uCWO{9Jz@j(aekvZ0RBz@bk@_%6ioA+%`8T4~Z{@QBrT z?9Hv!7|hR-5oUVle?}HXyOJFa8R4L^Lw=||ok*az%`d>NU#Bpt?@>AlDMzS6f!Wo5_N+0gxcO;4h& zdKs!0HaIBF#N!==`~*M56TF^Tm&4*35i6(p3)@FmWap|Wg0g<-1TnjE{h2=KPx{+J znLlZ^(o|XPsZ92h8FhMvGMTDAnJdng`v|C;I^kMnzP)A{XKjQUV7t2}xvR3ZP5&3` zugPi07GaX^arl&ZTGLXx7W@8X$Q=rK2%UAw7|e@8K1#ZtzgS5dx78wVP{KTXATR4z zaM5^!t0z<`>m^dTkCRYU7%jI=Dm%+?QL?En5J#$3}m3!gOR@MP>yzIX)lc{qipk->~$m80PH6K4f5-bR++_|2(Hva<7|3 znr@ZdW|QPz4?Dg1Da?~^!u!qw_iu{7xI~hzSRQJ3e-jJHd91?j+kUx|6j>Jl$>4zVJ+UirH+tQ*AHkwwtxKJ5Bq) zZ@ANAm&Go3XIT_6w@16T8{Ij!8*_KHot8UKH2ZMP(RZ92cawXS{C6$BWv+X@d%YrI z{y-5wJ)OyXgJg*}Y93>n$6u(-Lz>N8q==EwDfUcJuPZSW=up6pGQ$8d}8L@qMMJYaFdyg>>if&7J2 z%>B#Z{>8X|G45Y3(vnvHw9 z$yz*iW9&x7lhxBE8s)jGk-sm5Kt_bWp7zd8L#-dmBp z_ak|4Me^Q{G`;oSXKJ2Z? z+53^O@8Oz+y&nmCKN9vJcME4_! z_K1$!k0iPkNwkOm(^MqUok*fRB+-+RME4_!Zb1^=k0iPiNpwGw=*dW;`;kO1Bsyw8 zlIT_>(Va-5=Oc;kM-ttNBziuQ=uRZjlaWOCBZ=-r2Hk-Sx)m988#3sAWY8VRpcfJs zwG|n3KQidnbewF9i@H0~=YHhQE^_AuNSs@dI8Q<1>=6ZZ3KHiIB+mUvocBQ1ykJ1g z?1e~~`;jlVB43_@e0dravlaPrFY@I==w=GK*#zAzLcZLKe7O+$axXMAg?zae`Em;R z@)+pp1n6lBdfJ41xexhrFY@Iv$d`MOFBc+T?uF*=hI}~%&S3z0bYB603R;@peGc^X##DJXao6ubzDb1xF-6cXnm zsQCmW&V5Lnd!gw~NSx;(aV|vSoPx?vK;m2nt?xzRJQs;`A#^_l-QNv~a|-I;1obaM z;@rm?P=?&Okd>epxpN&g$DX~>{c$e{a>LDwOJUPzqNg~U1SC&ETE-U%b{ zP8g4O!Y+6x6cb^ihX@JJhcq)v=+pGj{v)TA7G~=(( zK!l9~ycQ~ueFylT#nAJ&G+h|Ab--{Q*45a_9_#*iDB233idNlfgR^o4r!!IEp zU+FwN*jmvL^rQdpLQfF-E64)LyTP;t(kx%8eQA^SKigz2_?UJ@ztOJ9&REr{R@$d( z52gPv>uZrBC2?1-#qs;FOla7Bj`mkisO^{1e}CBVD?uhHctow(*LJBod0P8Blbq-z zSB*;J`lydAv1BEqleWUs(_hZSp%U&jvzycZE&9)%R}!DJ9i4WIA0d6zNG{s(-E6Nr zChu6e4w)`+GZCTP-7jP#oDmN*W-E zqwbhV|K8B<_VM&c{unhNKzU|~rYK*Tdnn9f!u(9FJ+D^&M|DF9;BRHg_-nIVl`QBD zlidq?a$sBfjf6!1vm-}NnU=8Ls~q*NyOEV%N`6L5Sh)e2rTWKxT*bXVJotQYWMEP1 zPZFrFG(tE;f!w+|8!os^DsIDnBp|CAdR8$iw0j6gypd=q*~~-_feRO>xRS zXQWzM?fCF=u39@u5sJPXd|Bza!MRG+vJP}uj(avTVKg?SrrS=0 z8f%SmJNtwY>=5eM8#J;jsKXv-9Q%Pfb^>+m0miTg7{eZ*jy*t(JwSXIPtUDxk#@1g zZi&v3F(1#6@2`X79}kyb2bW(7mmkNDW*4~pdbs>*xcq#${A#%T&>OS?F25EozaB2X z0WQBDF24aTzZx#T0WQBDF25QszX8s^9&Ww@ZaxJ!UjZLq4F_Kh2OoNgR>Q&9hqg2D z=p(qJ;b}EF@a2tg^R9b9lO2fo>ZW6ptN4&a#U;FuFUa{;{a2zcc>xa7J4T=M7v{Bb4G33h=? zu7gXC53tLK!zG9D3dX}9R}SEhM__-k3;b~%Pjej3xDL*^0nRuN&bS)RI0a{%4`4QJc{XIu?uTn=Yk0cTtdXPkm3Zh$8)hbL};C(eT>Zh#xEh8xa@8*YFb z4*gXd;D%Fh!}V~(<#59(xZ!HJ;R?9n2DsrA+;BeJa0A?MJ=}0P+;9Wja5da;Ioxms z+;9qRxEwyX9zHk;A6yR~oPrN-fDg`t4{m@1Zh-f#hWAau`{u*@Ho*H)_oZnbDzbZJtDtNvsxV;*Vy zy&AZ^D)_uAIJ_D-yc#&X8aTWrX*aCmj_b5-zjRq%6F@N*;JUo=_;BSdPvGaVN6L0gBaRpkN zAC|YzTUzgbA?$BITJmf%db7zESMUs4_?J~DTz5;wH@stVDRC@ssU164^kwl7p{4(a z*5&N^w<;;#M7qx>;X8gO{y`^(A~O#ykl|c3Qqz6CD!tWq>Bq`qxq62u=uK_byE$Da zYs`-ArswiPJz3w?6LPJdjO$`|Xclr+GFP%QI|an$z4SPT!{uG{RBJck?bHfSHLg=? zCq0;NfpNB@rN=XC)@s(lFy>DTDOfxm^T$@eI#$36R=~P+Bp*A`s6344!)jH<3RQ)q zDO{UMS)0PxJEg2mRjf@_$d#&)D21z1C^@QNRq~M*#aWfAS(U=`(E{W_an_(XYmmzt z6d?Tx&q1qZ#R=os7%#F>YtuJ_Z;HdPcmgrjnmB7sHET_1OE@rsO`KIGNS|*Lo@`^M zo5jq|8&OEoJ?Jbhlxqrv~Eyq#I*v!;Z6jL(`j8Rhx4KIU+mq*g&J)9~ib_o=_6pCF2#V$d95mM}2XmuG>I*FX39{QY# zMPt(Cawu~Zl(`(rT#8hp9?Dz>WiEm;C!x$?T$)mz<6@|B5^7upHO@q&v9ngnkv@df zIEloe9%@_y1ulmIS3!G6Ky|}dG+_jTFcwWcl7;#-9X82AJ=8b}9j<~7hp}ktd6$Zz z#uZTG3aD`6eE*57oXZb9?Je=ioVtlgjVEZT({ z?0-w?Nx&ybE9UCFJK=TuXQAWz=epyRzTmw$pwE0!^_Y94XOZ*$__J~8ALFkk6oWKz zK;kITEYInLn{{*o>4+NGQ)%h|7pQynGg@YkKu z>`!(<<~tVa<8h)4S2*K!2I6;}i8}Z2HfIWZk{<1ie&)=P1ol_X9&m|E*_rGwF7bEH zGD%VY;Cx1QyRYg*sn=zndl<6O&j){v`OcBz=;F@5h?h$`U(j1z@0=zcY>e}@*x1-O z=j)>F6P#~|2WxgVNEX@dY=n>c4`}xldi&-$-xk-@=WL4Y5tAN6@7LbW_2P(@IydrW z-5OgSTkhN@{^wBVhvIgQbMDdma*Fd1Z^y&D7mw&&__FgW@gx^Gzt;1AvGbJpjjNq! zk(a%x=lOQ$EuA*%m0$6H@)xLIr)2%0Ki54Z`t7?%NMm@k{?5?fi5lb8pTeJFE)UbL zFTaSe-*Y~}+3$tY{H}59laro7;WwG1_6zk_ZoiY&89cwvAiW`3m%IyTY_d7omMM{(o`KZr z^ZFZf9m(!Y?yxf%%}{ayEiYEzOAQ(@FE&FfY=(yW4m(3@RO7_tsYO>7Y!P%u@|=M+ zlk0@LD7i7jW#=lnX<(^=aDJ_7Tx*ytl)NE%TR0nrPhXpjlzW-Izu6}d=v7MFsI~z` z&!7FuE4CCU6+t!pw&$-Q!i|rh$>iFM&#@;bJNH1~D6vmeV_5_p5J9{PlshuQ@m$$c zl6P9>Dal(K1%o5!7xFzq%r5P6YL3p9so`3KT8_IzZ5&nR40xg--#mDLTIJbwQ^W4TjzW zr~V3$v~mMx?JWITOWk}@#uP!>R;<>A8GHz3-^=WCU?mE#Bh}Mccz0C8Ms;Q3eT5Ge zovr_m@GGQTV~U!JYNK-Db<8U2Et(HbP~r0t^b$~ZRD+?nl^b4pc)gB($ElIMw)OfA z)ho(E8d*^#<+5Wjs1=;$b^>KbwWMfy(IRjL9R#GY6dfjr5fq&QWPRv*^)=}H2+C5V z%M7Po&}p{+(T=E(v`Oiuzz31OV!7VA-k!qGXTLO`@?SPsS_?}rA-yYveYN21pv)@L zgGf&%HLFe6eMM(HyZ&Ba#(^0Z!tQ63yBqL4NAWS;*}$`a$5L`En6Z@H8+fs$Ua$8P z_51IP;U3a|C-;5QOVjBXwJ9B*rC?69)O!NVi8gXCX|R_JbAeZpdpMYHg{hTv-zS|# zdZ|BNm`j1bM|tV%g!x{G5ijj}7f^RLn10Ilr(v7a3Vs&3JjPreF{xIr( z&r;_;F#TXmJL1pcDI(r&4YV|MaN>E(52 zhsuwTeY5KpQoaEEe|cX}nfJi_losx!?s?QbkKWI-U6`9=u=_1aeucD#)NICG_YKk- z8^0Sqy$_K))$pEA?o=?HVQLuXur$VMeT%vd=@Rej!Yl!vP2I~#XNMR!q1?^X-8G$B z3qH9y)Xf3@3bk^$JB47RJ5rcULt>s@LX zPgb~U$F$b2oHp!^%mkhU+~8fW+;a^h8%s;iWo(NK_P8!@WV)U8s@q4cW=7l0Xm43wE=1^sd=8E()&#%muWzh_Rh#82xsfT*D$6lMce)?8Jo*f9ET*jVnu$1xn-b z9SNB>C%i9C!7!XKI6O~8t{Ss zUa{0IbPJs~NyGfDVL8_$Z>(F#x6QS0xm(Szv5I2RW>@E3OnQ~2eidmYsSEyf(u=@I zCaLmTyOhd`Sn1WIk63EdPU%ci*&PVhGpqCxQmr9^uOnSYs+B>QS(?pe8-r4fL8)3+ zsvec9ccoWn=U=n0mYg>CNX>sR%>0|ga)$C;WS5R?mmOD6>;K80=z-?=pZh0HVc0f5 z?ixRO9J&+UkL-TfTdDLer&#l>DB}8?tZ%#G{`BcPM}G_T-AA%ayL*)OeM#2V7){@? z(0dO&5;tG=C@S+!%k@vQTwk-RwQ*$&oGj?vLCjyo7tNm+Q@Px0pS*H&&M1N67=?81IYT5^2+J z_EySk;kVvKorTxv{a7(hI($!O)_vA5(;0MU`O_8AWWCOzyU72hf25+A+~yze-|pY3 z*d}-R_xNA)?+s%92E`^R@t;&Yk|zI;I{9s~|2M@QSt*hxnXtR@|Ku-Fzm9vvpg&~7 zX6VU^6h z3qgC+K26J-`et1?>q4OR2s$8wih(Ap+)$j=O%5q%xNNyBlp3a$5N9=NqE;FrC_9$% zQQhH2+7;Ev_BJQNWos;qa9JpI!O#7;pcN6={zbXEj?bnaR! z*M5*%xo`4eO7*MhVxUU}UD0%PI`=xmOoXnHBay&knP+*q7UxojU3;}I@@ z7$|BbtkL?m=6{Tp18OqJ?nleI3^e(kokFdH$~_d7do%-utu(jIy0E!<;u5tyOMkr+ z=PO;5!I3-NatA=wncRtIPdtC(6V@JWE+;iyI4XnIN4PAM%{?f})jd_eR$~p&@tKyv zWow)gmCLqwdW2&v)F2o921|i1BfV1n+!8_809~KKwKNNQqGftZH_)9CbWa44JMsQO z<%YvOWHlygw!`)&J|pObiLXq2bK+LbpGUtRWT5aa7!D{Wf(j#OIuLUo;mU`>)qxvp z_b4hC);+cPjOIzXfWHt6UGI&m1N8{7(&%jSkSt2-~Mu^@u7?JbUQ=S0v_AZu^9 z5gZbh)0j6g=2Hb74YXnyoaG)8l{+znc5+2WL?g(K1&CVd-gYvo?3E9x%lw77jT+14 z*4BXbZWHbSej9Xc1l5cZH}PFBIvmYdNP8tHNxC2gId`} zxh&405Vw8Sg_8oyZM|DiYEsRIpyUwTrBS&EnpB*@Oqwxk2-@c(p=`MZ z%8lPiEA3G$L;Lvn8rczKd&}bHL@oD4(837HmOB*OSxS$!S({|g+6X#1f=-K|F!y$q zyJFIPN)5U?g6@u>3nS=aAe-IcYFrnUyD5TbrEQ&RJZ1d?Y4uD)k3`VpKzfJ5a+8}T zw@$7#98i7)b!MPRF9F3>ZYWN5Cp|x;oV6E~%R-Z0AEuQMXRW*)wensDnw%Yr6V)AV zq@_`fY`>KeE?Z+vgv&xmaWF487Sm8TFN{7S_%yZ{uxURH~E7M)KdLnD4RR^g-q_`S0d<5gC=jy zv^=CeFH>$n%Q+FQFoNipUv-uOjU{c?7~9|g<_TI1Zb1Z{A?Q?a1}%-C6%lj}&=G^m z9Wo5=XmENP2ee1ssY&71k-JgQwJkR&9SmJG1b2BjnaIdy(X?aq=wznAcKm@(` zkx;hWZIrufC#~EYwKBAikFSv(LAJLnZgbS~V-b|?UY?Opw?yN8gxJe9SL-7 zRPOH9`&w@TXV4W9^k4*?26U-%hvKZp$wSH+E?X`Ooi$7=AhTeB4SEXbZ9&gR&`S~YdIWuR?t50wR!QwVKj`p= zg-(oe^`3|2rZ}@MoD#PhQOPr80uDebh#{ zF;OeSjb&C;F55?MgquGETBK`P65+xcYo;7OI+I0g0i>|B3u^A<~|hV zJ{mz!04*ETa<;|`QMstSwzdfON(8+bL6oy!3WcK-C?|pn`CV>Tq^r2NO;B4kP+f!@ zD_pacn|grZIyQFP3v^-xg}7yda)-gSwNc~9Ou4q{YPq{@UfY7U#nFhCMv(4I+c}KS zpcO!e2s$FdY0Ubq`!S&0(Zk?Q1*i9DKsoA84W=gBUY(knS_AZ41Z^J%+Gx18+f*Z) z3y!*%M>RG@P`15mGq|b68K~_BgJ^HK5!^-YW197aj9yUN13>oEHKEE!0xWXG~4Q?6}W1VvY#sWCPAA*expk7opv1+@cp37P}cCx|PuXK3oN;0)R) zg0v>-x1OdC55p-Gvt&O0wA}CuU%)N9_D_2l1i!&(1-7VtyoI#5s=&%UtjG$RSy*sI~Br3N&g2Gl#QH}G#8MG#Xj*p z6V=G}c7KG+)_63+Wg%*Sf5B3qS4iK~3~e>8rDJi&(vD`s0kuWYicbjTP;RVR$<_#Q z)^cIgN_hlj`>2j^bx|wBjb(aNF55?Ugqt@Qnz=yNqQCSNg*6W8IHKcdaO=`5-Q^ty z*?Jj5wl-egaq6Jl;c#bA?wn!DZ4&NU`glOla~&^syxMVtpxZj`>bSQfi_1cfMdb{) znHpK#lbPHZb}d`1WrI3{4AikLg0^R%Ft>BE%89BdHK-|C0EtiFk9Hx~J zXElzES~)p_vST?dsyp0BH5a;?!Tnww;j%TZh;Ugb9N*ole>=Gb-3RobphtjS67+Zk zJrzOEN6<&-zHa5FIr?krI$k=o=hWWYo$sY_al=i^*I((hN~N{>qujJH5!5QElX9m| zJA2wGv}e#k5p@11gl180x$0(Xgg9$YG+#X#G(Uo}eJqM_OQKeW8_Qu)xojV6BAl)^ z-A5M6wnB}rhh|;a^(f^wsO1E3=^xzk>l_R91&Yi|ftoxx3e^TW{eZ0et0Ux_4=4 z+ebp#a+@jl*iKr}-A}hSw2zOkksU#{w=C|(Ov|%$SJQoLiJ+)lm^dts?NI7dSTP_R5hiN6mS&jUt zmC^{xj-@iHJKRW{q8i!WS|ePx#;gdJg~A%kb4*deGuh(Kskfji^|O` zkIK;=zp5i#T?A#vk}cP5xs;ekxzypfd*Lo;nQf z9B}Ifl?&@$E8M*^A5c0N+B5`r+n{nckekKb73FT96&Nj^RV*$tnE6};ZTm9ADjj-IT@ybc*??Rx-5mXaF4G|RP z9-!ZS;0#(AL5D_Adjxd>%~3jBjeVkW%OWUjN@S;;`!7~dv=8|mhzXHeSL7e)eVjWgLjR4w%M>c593|)B`f2eYOOgBn0J*>x;#|U*SKBz9%P4u7dxCO* z4E|}x|1_;VZI~eR5Zl0N6|JMzI`Heb zqILAOj_X?I|EGFcM|_%fw6o4y_7>CrI=ebq+1qtBhpCnEnyqCIk0Zf$A45OG*^F&A zJ%+xNv(veHW>m)BxX|NkHhqPjmJ2Df5X?eaSjcGC^IosF_u3oJ{mS8ft>=E>CFriF zul2OBo~v6=FKMqru4}Mwp^cwsCgWjfb%PV^dV@7KhM*g`+uld#LEhgjyp@mA`*L~@ zeI1uG+U1NP;{$0|x|}gA=h+CKgh3vRTL1Yqgwb!}2zAVRRLtzoqjBdO6JS{vyg;!rOGa!Ja$~EVVWjQB#<} zv(&wa`Miixea&+H@AEc&jnQ62nXg%0l~iByxU*VgfE&R#GAE6cA46^f-kxiDCfAa? zmix7qzSeT>Yk3-ZkKDD~yS22rmT`WMme=x3G6rv{wd^gmGD_{4#D7n)J(K6s*SU5T z-q-2zTt;$kI@j*hxz?{d-t1b=rLRTgE&|>U{37OIKUx^&TTIkZexUSL?@vms1!oO~m_lDrnwEQONC@B9g$^9*uUs87>n9%!lB4s9! zJJEc+G*fm@uLA$yjO4qFq=k{RFp?H4>9#PQ7FuheOaWP=-CA48P|Y_$kl89y|k~r|uq< z--FinpszjXEA83KHOf0uz3)L^p=a-lR^G?Q*uNJ1AM6eCu3&!dqpwZ$)l6TZcd_|s z%2SgbLx13m@3Gz~d2re_HuKE1GXt#VZpMFD_jHKou)X!?`sXRVpEg+$1lzN5zl~XM zsJ&C?@=nDJ_V6C}YI!PNqs%$n-)p$PamvF-IcM@DykspqFVW_il>81QU9NO1|Ma9LVxMdV|fuXj6buN@np8^3aAy(j@rg{ z+y{P{XZna9^yMkTD3WJ>stVibpYg4fLb-07VXeNcxOgh{(=SFKs7|ot@Ki7Ca z?e~T$qh$}}_L6%6BX2jncPG8K^F&=h?zh1l?b@}h1!foHvb%9F0keV@RxleYtR4SL zA)fhM5yD*E3dZnP=JPkq=Yh=Ufz0QD{#^BPAR|1GnLLn|4`e*Tk~_~;a1+eJLvJ7^jJ@i^;}Usem(8~k+hzE7XmLNcYn{``hB@;`;)uBNeSG2HP^1YztIQhQSQZ~ zygQFtkHToQ&ZE|&PUo}x@~HKz6xiAiBUuPz_w>KO{}=5O1H!ul%mwab^>VVoUczd5 z32Wa=7{>h!*Yz2$bbrJ9$ARCU(S9a`xt7n+%NDy9XA8Y=u_!#w7Dl^;=VuGovc=7} zt78uLwOn^!=51g4+LzhemzMYS?XK<1n4zd%7zJZrn+I=yblO%YxVZ_jXw+!XLgt}ew4jAXPaYe881*#D%z zEbj`(pVzl=iBrDv3&*c<`qmtL;?d%;jaoY5q>a-oQe=xs&Maq7XSwrv=M?7~&L-z( z=U)8g-*C3O1#XSj4*BEv?!Hf*v$%KP`E|}2yUyRQ&RN^P=e#;+{l5G3+W8G(d#+*w zj8;s5*@^@3S)By;1!seEmHhI5rU(_kciwb%C=$gei?^WOE9Bi@;?y}UPPfzVtZ-I4 zr;6LV#JO6Y`}aBj<2>)Yr3bCZt#v0+-gUJ5g8x4+UEfz^j(VLE-s3ECKIg1a41n{U zjm~!!1K_{p@&5;Bi`cAUceI|Qu)jcO%{Mqx6sce@=K$v@=QQUl&NmfVrKeyu10 ze^FG761UE6QAC5>xyyIc*%iCaT~g<4+;tzN59~R2d7ZPZf3Jmg?)XIu=heB(_Svhy z&Rx4iW!&4B?6YT`D;|P*wUfacoi?58z1TU>IokQ6bE)DJ+^!QY9#>rNw_RVS*wwqO z>2bw17h{~MPOr1KbC7e4bGoxm5uL7e?r6%pj;iUaZ|MLCEmmPez-f?%F=oDt4gou@v}+1EM5InFu5xzPER zA_D!$c~CJCUUL4b`0W+$7fyNj#$mG+Z5vv$1BXzz3Oa}IS*aL!UBlmAexk{>${IlogJl6MtrWQ04`?MRo; zQ_PhK&U8gQS?a8EPSkmUUvsW-e&F2g{8BL+{_MQx=DL;cINJ--e!eqOv0P?2^PT;j z!<>_JmdHhl^l*csJZyHJc3ySfcav_FVmWBnMfn1!#+j&lxQ8Mr9PXU#eA)TBBB|V{ zr}Sa%6kk(ZlsrW`ncz-OmoLomTQM&Ny;)XSr z-bQ*C>Aj>6kZvY@jPyy;=SW{9eU)?z={C~s8s_mi!KaZPqegR*pGtcCp-1NwAM+`s z$J&@HKaKPRQMsJjPbK~Q(TC-XIpNbtk6L+bPSXjWMtVZ)l$_QRK8^IGLr%!)JmFJG zk3Au0)(I#5^V1XUsq6hTQgNf6{)~6k32LNcmBuX!lz3K))@D0_Ao^|P#!=3stG>8| z8m;7p9ZyuRFO6+^~66T zLl-A%^^lB<-!ga?(k4=NmEx-m-yn{AMf{nPOH1dMUSE2Bxu@@SN_X;E~&V; z;_-?PQmNFe)PmHq)Y{ZxsS}lMNIf%R?1=dz4jOUFi1j0`ui93#WK`d%!$w^=>cWQ0 z8>g#%>m$eUf?i3y-uFK6{^o7>cK8aKq}WuxANVmp?kD^lzrk;+6#onUss6wEr}Pxrs%pW&aWNLc^opY5OHpX;yn&-2gs zzv8d+FHjV$uPQp$*AyM=>;5u6ULu4#(BHN)@nXZo}J*?za*}a^ z{;i50_CrMvyF>BAG(-OVey8`e_l*B5|55*c{Kx!X`;Ys-@t^R2>p$uL&VR~(+JDA> z)_>0bz5l%b2mb~CkN%7PpZu5nm;G1#Kl`uxulcY0Z}@NeZ~0sNzxZ$a@AzB&zxvz! zcm4PL_x%t2zxmt!9XjArV#>e|f*=;e6{##I$PJP~UXULY1cgCSP#ly5rHWlv9#jOW zU_?+ER0Y++$e<<|71Rc!gSwzTXb2jEF~Kgu*kD{RK9~?R1rrtLY*H{eXi=oIDM4E> zHE0hyg3e%CFg=(NbOkemS;6d}JLn1K1apJlVAo(?uv^d<>>kVy_6QaPdj<=G{$NqC zSFkwPJJ=`KH&_zv7c33-50(X=36=++4ORr73l0bl3=Rqo4h~T?wLj>DkQakL>1^ef zgFgqa=+vLr?bJBVT6~++7XPXf4WA93(+P3!1@G(hpTF73$vPd*jd?L&=flNxGT1kC z-p$22GyPk!%XRkHnXzx{)Uk7Pvd4FHTFuou=jJQ1b+HR{u7{lrwO%JZeNE?meBDm0 zv9r~6vieOr|Mr&Ht+Cr;KaAb3b89|`{VldVwj-|4m2ofb$Afq*-Wi`BKPY~%&W|}f zenkB9@nhpN;=S=*!PdjVeXWiGGQ{A`R zcbxNe(xT^l)eF2lNs9`+NzT7ZcGu(F<<0f_oL}l3t0SEM;RLH!y%W3>oY%b5z0(zI z)=oWt!+TZ{1>f>>{d%{+ALBQ>WBsZAOt(evd!IX9v}2%om}IdZRexAU)GuEC%J2bF9u(9*Xh*7Gu;bxX3YiedOJnY{f3=Z z<8H8XYTQfg>?(JoosH;zQzst&#J$u`2X`;G^QYV^f=7Z!-0#>qHSQ)mr^dZX=WXY> zSI3gEr29RcK~v&h8>@(=+#lE(Qtpkh>R7dVQ*2ahlzX$C9_8Mmle5RUx9L=xN$#C? z2DbZSJ5kKN+fJo%e`2RWx%cQinmyc~>dfgw+28GF`L#JDr8p<~|*t8K3JuAD%JQQ zLHq~qmiUeF8{NOeZ;s#Wz8$|ceyjVA&V&1fyVcI3?*tGe$t^a3=^)~sO>bQ}lV!r&4VqKIgSs6jRnP!Ne>3?W7l8zeydpm7)? z`ywDHA~B32BDU-_&7z_b5}O?qK^nwn4d#2Ro9>nmIyxWcGx;N*{`9Zky|-Sy`)*a8 zI`#XVu5((WFbtEL$-bJsHH(?Jcm|Sap)}WiI#37GZo_r7KCR<)lFraMI-lKx7i+Gr z(tL$8B!m5K-LHjOM3!G=Zb~zmrlzTfmA{CY=}Ij4^`;#&((Tyjp3Ff5m~S3tZW+N$ z@(lCF6fEcqSj$&w-(_Zv*?>jdiuK!zr8|OEJA(yF!CGZunHpe)F2>@t#JaS_l61ss zbW8LiU+aU3L5WAmvpJF+MPm~a!a-!6pPiUThSWugrHK`Zd@@#UAtU8(EJz_4T2Ese zk~Ym|(u(zLWAb}7r>(9gyJ9`{9XYv5c(SJ_o}b;wNJj6BnqyH?nM8(ar+QFX>T^kM7|bc4wy zHQbGMPrGq$lAA#`=J{?RwjkH7BJ1+Iv{ixI?e@DuSL9B!|7{YRkjeP3$5_88Y#z2` zN7}aRLEACBla}knxPLGl6h0E>gd@W-;n;9OI3t`B&JP!ci^JS-RhS>X8*T{;!rkHi zurMqNPbW2*Or|9>lQom|l8uuWC7UO&OkSP5KG`nWF?naQTe4TOUvgk_aB@g;Oma$c zesXDYL$VIAql#Nd=Ed8h9K{SoMTtfG5ddt0t1l9;<*UXclTJ2wbSCC|O`CyJxFOlj>l) z)BrQ2CRhp0MNMVN2CE1;u}!Ab0jr_~sL7IgU^S@^R+k1~4fz3BQyPM`q!E}cjltUJ zm}=_C1z=ri3f5y!R5cA@dDS$6n^n^o##K!dcvCeOz=o=63RkJ784RSF3*i+NYuf^B z0SBn&M=*P8E`zUQ?^9ScHCGDz>>Btouq7IuVwYQit%$l(a}}DGnycj+@EW-myq5Sf zHLayJc%57aUN6^!ZKMs@R@#C;kspJ%u^YddPI4o7yR-wlqCl#-L)wFP%FW=XnaXf-cLZ}3Iw1J09s!I$Jd zaK7{fUlw*OHVfo_@Q>0Td_|aj&7WidxKMr${dm3RC7k4Qj_jdYQnx#lkQP! z(!EMex=*P|KUQkePn4RN0Y-zL>hHh<`XqP|#hekSW57fD6j-QFgNOC^;1S{~7=gqP zFap^rnh}Tw&j{3U;4%FJcwC2qLZA~_g)It$Dsrh&1Ca?jY)Ibbz*|7Yy!3t$a>5v-~6z*_nem>utBY-;Pv zU>#im)=D63&(lAF4Rs+)v~9B2v|wM`LeqwGH<5`zO?!P6yjfoZJLn?t7JVJO z6@`d#fhwn_BN~&MpQ3GPqPL0rVva858@Kj-dm>pP=+&AFPS&>rqwUQUUB=N=T@Fsu z72tGT3C_?};1XR8zNu@#rMeb;OY^{7;*#l0nh!2VeWEX+N70v1*yu&N30$M^fNS+# zFi+nD*Xd?3U*8AU>j&Tl{Se%UqD3zv%0T1H=io==@l$5l!{E-u4l<<P}+X8-J}x(ZJ0 zF1wNA<94gdVy0HR+iv3cg#C-F=2D%pd+a+LpR|8v4o`ClX7+bEK4m|0HC(#0cAw>` z*j)QD__qB7TxR!!%k8J&3d=LFEA2sWmHiA{Z4ZHKY$3ST9wuXB9>44O&F2>tk^2+w zNw^Q;vxUzSKEvSU{m@+zsH^E(f;}D9%iZI!USz4ndb!@Nd!S*XuoKuMyaQ|442C6U zG@A00jXKvBPUS|FsmoAP`l8hh;OACUlHr`2%TIT7twli()R+R)sCc*S$79VZ7$Ku& z7TFILN`CN)Y?O_`Iw_EXAfK%3hl2G!)A|Oq(Tc%`da+&{Y|(4=+ThRZuzgFgRr~4# z!A|zs9vJM?hxF0lQ=gai3!jU&D3O!M367B?a&BA z^~*SWFI)cS+V@211&1Yz+@Ou6nY+|oDi@O9vy)sDy3olbVH8HpZ;o%CV3kvkZ%MvG zjs)#Y_}($Ea$(7tOrBFVno;pNVZ0Xbos{Q!CZ?$HwIWJNkdCLk%k6Rd@WKwbgYFQ% z*b%(3lkSu|O=f_&%n<(@e@=1zF+U|ifB(tx8TPVg5sv1W=wq#nAkXO=+BnYssTcUW z)gXm?DZbN7d1o9sU%sXWQXI{ajGpcgNy_l#gN*oT1hw!LqaZu> z=P8%)H4q_(r;twlSF;Z6h|)Izz4#e)#8v2IThZZ)@Nx{yQ(BPew(~6ZIL0sEeJ5DN zT_qeNyyVqh|B5@{a~TCZB}PHXHF~_;<;!CQ+`iH}Kj&zhI~t#JUw}oWSC08B$H6`B zM11}1m9PT+IwPzIRt{6aI4&U(rkB2|KETpyqf28`-2V2)p4&c(Z`qQ z>r33{OT=x(>JHAJ2Bk|@bH2x+JkHl^GhWCRwjXdH9avvxe^tqpy> z)KjihN<7C|;ve}t*WOs}3h(z^)Q*@zir)|OFqJZ`>@}sOgi+VL+|jao>G|x^^F-d-)6V*L zO3XO$>TEs5eIR~sG2>p`&e$^<{WUe^+O@uB4Tdu>l=Zy0&&BPWa9i+QD!RB&3DG5G z_wUFWAKyzJvtIE%m$c58SRc+~`@eeL_hyM_hI7u-D$KI}PI%Wop2yiwQOzWc%r@PQ zce@j>b~oPaUcA_k@m}}iwI0A*{R}U)5byK|Ug=T1(IULi<9MGZ&%yU)*qxArV} zn^GS9Cb+V5Isam2yz6g_R5RVoFwcEw#(ar+ z(=0V_k$2;57^3B7g;@!Qz8bD*t;sX%OuktUYqZg9GMAsjzxKpq>V>CNo^ve-JHeU8 z{!-|zVGwg`!I79-3y$Jf+!dT~>tM_b^Jypv?_Ie6vz}C@>3r9IRR3G`r2k1#DeFt^ z&Z8fFoyzk6)04{j(X@ZCo|J;eOpL1>h7<1tC*C#~j5jVJf=Zu#b``CU3@+0gvJabSX=9z=k*y|3`VxBpu z9P`XUm6&J7XM|@Cs=_np1zFxNtrq(r!4JG&+Qj>%&AngR!uzF{m75>pxysKEx)pCE zjzErp0 z6t$7I@?*I{Zj^R%leCwcrGwl;9;2U-$LObIGU`MoqdVkI`I&Tg%Qm40%+^p^)@fc#t@lwZg|`44$Wekp_GS29?BEf33Yo;bQsM36FP!inIm-+9RKh1Npe1p(WhYhf3MHz zf9hEMFL?hy@c*0Rb%IVr0hp{)bgE9%>1YAZ=}euav-NpYfw}sEzNqu`CG>%pb%Fj- zUm?fRLUJs?`X50t2H{=fI1is`pkOm`=~s+k@rRZS0{qnmz{W;(G%FP&Rp=*uPX~92N5zD2%b%I0m&bN1pO(BU&SBBU&SB<9M$y zPVfrj#6+wxPW1}obgwYZ^a|rFuQ1L=VRZ65>y~tx!@8xa%=3EU0#+^cQ5c(|BrfzC z;_F^9TfY)ydkEvx6h^Yp{rmSkLqwhl3Op0Ux{sA#yt3cV zY!O@hbZ_yic#B`hTl~7-;@2;CXAOgN6uaK>?|D`9A5u1*enZQ%UT}~aNf*K8Re-Nc Lg_BF?GlRba@aD!@ diff --git a/CoroutineTemplate/app/src/main/res/layout/fragment_home.xml b/CoroutineTemplate/app/src/main/res/layout/fragment_home.xml index ba885d12f..67fc9975c 100644 --- a/CoroutineTemplate/app/src/main/res/layout/fragment_home.xml +++ b/CoroutineTemplate/app/src/main/res/layout/fragment_home.xml @@ -1,32 +1,18 @@ - - - - - + app:layout_constraintTop_toTopOf="parent" /> diff --git a/CoroutineTemplate/app/src/main/res/layout/fragment_second.xml b/CoroutineTemplate/app/src/main/res/layout/fragment_second.xml deleted file mode 100644 index 2e2b65d6c..000000000 --- a/CoroutineTemplate/app/src/main/res/layout/fragment_second.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/CoroutineTemplate/app/src/main/res/layout/view_loading.xml b/CoroutineTemplate/app/src/main/res/layout/view_loading.xml deleted file mode 100644 index 0ec4df1f5..000000000 --- a/CoroutineTemplate/app/src/main/res/layout/view_loading.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml b/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml index d17f16eed..152e1aeac 100644 --- a/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml +++ b/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml @@ -7,38 +7,11 @@ - - - - - - - - - - + android:name="co.nimblehq.coroutine.ui.screens.xml.HomeFragment" + tools:layout="@layout/fragment_home" /> + android:id="@+id/homeComposeFragment" + android:name="co.nimblehq.coroutine.ui.screens.compose.HomeComposeFragment" /> diff --git a/CoroutineTemplate/app/src/main/res/values/colors.xml b/CoroutineTemplate/app/src/main/res/values/colors.xml index d442e10e8..a88476cc8 100644 --- a/CoroutineTemplate/app/src/main/res/values/colors.xml +++ b/CoroutineTemplate/app/src/main/res/values/colors.xml @@ -1,7 +1,5 @@ - - @color/blue_free_speech - @color/blue_tory - @color/red_violet + #FF99CC00 + #FF669900 diff --git a/CoroutineTemplate/app/src/main/res/values/colors_pallete.xml b/CoroutineTemplate/app/src/main/res/values/colors_pallete.xml deleted file mode 100644 index 1e3f7b65d..000000000 --- a/CoroutineTemplate/app/src/main/res/values/colors_pallete.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - #3F51B5 - #303F9F - #FF4081 - diff --git a/CoroutineTemplate/app/src/main/res/values/dimens.xml b/CoroutineTemplate/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000..76beac899 --- /dev/null +++ b/CoroutineTemplate/app/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 16dp + diff --git a/CoroutineTemplate/app/src/main/res/values/strings.xml b/CoroutineTemplate/app/src/main/res/values/strings.xml index 5d857f56c..0b4738759 100644 --- a/CoroutineTemplate/app/src/main/res/values/strings.xml +++ b/CoroutineTemplate/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + Coroutine Template Unexpected error diff --git a/CoroutineTemplate/app/src/main/res/values/styles.xml b/CoroutineTemplate/app/src/main/res/values/styles.xml index 0eb88fe33..6190aefb9 100644 --- a/CoroutineTemplate/app/src/main/res/values/styles.xml +++ b/CoroutineTemplate/app/src/main/res/values/styles.xml @@ -1,11 +1,8 @@ + - - - diff --git a/CoroutineTemplate/app/src/staging/res/values/strings.xml b/CoroutineTemplate/app/src/staging/res/values/strings.xml index 8ddda015b..5303e3d32 100644 --- a/CoroutineTemplate/app/src/staging/res/values/strings.xml +++ b/CoroutineTemplate/app/src/staging/res/values/strings.xml @@ -1,3 +1,4 @@ + Coroutine Template - Staging diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/home/HomeFragmentTest.kt b/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt similarity index 80% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/home/HomeFragmentTest.kt rename to CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt index 4f8dc795b..0879ca164 100644 --- a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/home/HomeFragmentTest.kt +++ b/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt @@ -1,5 +1,6 @@ -package co.nimblehq.coroutine.ui.screens.home +package co.nimblehq.coroutine.ui.screens.xml +import co.nimblehq.coroutine.R import co.nimblehq.coroutine.databinding.FragmentHomeBinding import co.nimblehq.coroutine.test.TestNavigatorModule.mockMainNavigator import co.nimblehq.coroutine.test.getPrivateProperty @@ -25,10 +26,9 @@ class HomeFragmentTest : BaseFragmentTest() { } @Test - fun `When initializing HomeFragment, its views display the text correctly`() { + fun `When initializing fragment, it displays the title correctly`() { launchFragment() - fragment.binding.btNext.text.toString() shouldBe "Next" - fragment.binding.btCompose.text.toString() shouldBe "Jetpack Compose" + fragment.binding.tvTitle.text.toString() shouldBe fragment.resources.getString(R.string.app_name) } private fun launchFragment() { diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt new file mode 100644 index 000000000..d6b090dba --- /dev/null +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt @@ -0,0 +1,15 @@ +package co.nimblehq.coroutine.data.repository + +import co.nimblehq.coroutine.data.response.toModels +import co.nimblehq.coroutine.data.service.ApiService +import co.nimblehq.coroutine.domain.model.Model +import co.nimblehq.coroutine.domain.repository.Repository + +class RepositoryImpl constructor( + private val apiService: ApiService +) : Repository { + + override suspend fun getModels(): List { + return apiService.getResponses().toModels() + } +} diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/UserRepositoryImpl.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/UserRepositoryImpl.kt deleted file mode 100644 index 17b0ac7d3..000000000 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/UserRepositoryImpl.kt +++ /dev/null @@ -1,15 +0,0 @@ -package co.nimblehq.coroutine.data.repository - -import co.nimblehq.coroutine.data.response.toUsers -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.model.User -import co.nimblehq.coroutine.domain.repository.UserRepository - -class UserRepositoryImpl constructor( - private val apiService: ApiService -) : UserRepository { - - override suspend fun getUsers(): List { - return apiService.getUsers().toUsers() - } -} diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt new file mode 100644 index 000000000..6484bd63c --- /dev/null +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt @@ -0,0 +1,12 @@ +package co.nimblehq.coroutine.data.response + +import co.nimblehq.coroutine.domain.model.Model +import com.squareup.moshi.Json + +data class Response( + @Json(name = "id") val id: Int? +) + +private fun Response.toModel() = Model(id = this.id) + +fun List.toModels() = this.map { it.toModel() } diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/UserResponse.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/UserResponse.kt deleted file mode 100644 index e44b28eed..000000000 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/UserResponse.kt +++ /dev/null @@ -1,62 +0,0 @@ -package co.nimblehq.coroutine.data.response - -import co.nimblehq.coroutine.domain.model.User -import com.squareup.moshi.Json - -data class UserResponse( - @Json(name = "id") val id: Int?, - @Json(name = "name") val name: String?, - @Json(name = "username") val username: String?, - @Json(name = "email") val email: String?, - @Json(name = "address") val addressResponse: AddressResponse?, - @Json(name = "phone") val phone: String?, - @Json(name = "website") val website: String? -) { - - data class AddressResponse( - @Json(name = "street") val street: String?, - @Json(name = "suite") val suite: String?, - @Json(name = "city") val city: String?, - @Json(name = "zipcode") val zipCode: String?, - @Json(name = "geo") val geoResponse: GeoResponse? - ) { - - data class GeoResponse( - @Json(name = "lat") val latitude: String?, - @Json(name = "lng") val longitude: String? - ) - } -} - -fun List.toUsers(): List { - return this.map { it.toUser() } -} - -private fun UserResponse.toUser(): User { - return User( - id = this.id, - name = this.name.orEmpty(), - username = this.username.orEmpty(), - email = this.email.orEmpty(), - address = this.addressResponse?.toAddress(), - phone = this.phone.orEmpty(), - website = this.website.orEmpty() - ) -} - -private fun UserResponse.AddressResponse.toAddress(): User.Address { - return User.Address( - street = this.street.orEmpty(), - suite = this.suite.orEmpty(), - city = this.city.orEmpty(), - zipCode = this.zipCode.orEmpty(), - geo = this.geoResponse?.toGeo() - ) -} - -private fun UserResponse.AddressResponse.GeoResponse.toGeo(): User.Address.Geo { - return User.Address.Geo( - latitude = this.latitude.orEmpty(), - longitude = this.longitude.orEmpty() - ) -} diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt index bbe4a1429..b56e5d19a 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt @@ -1,10 +1,10 @@ package co.nimblehq.coroutine.data.service -import co.nimblehq.coroutine.data.response.UserResponse +import co.nimblehq.coroutine.data.response.Response import retrofit2.http.GET interface ApiService { @GET("users") - suspend fun getUsers(): List + suspend fun getResponses(): List } diff --git a/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt b/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt new file mode 100644 index 000000000..340269167 --- /dev/null +++ b/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt @@ -0,0 +1,44 @@ +package co.nimblehq.coroutine.data.repository + +import co.nimblehq.coroutine.data.response.Response +import co.nimblehq.coroutine.data.response.toModels +import co.nimblehq.coroutine.data.service.ApiService +import co.nimblehq.coroutine.domain.repository.Repository +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.shouldBe +import io.mockk.coEvery +import io.mockk.mockk +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Before +import org.junit.Test + +@ExperimentalCoroutinesApi +class RepositoryTest { + + private lateinit var mockService: ApiService + private lateinit var repository: Repository + + private val response = Response(id = 1) + + @Before + fun setup() { + mockService = mockk() + repository = RepositoryImpl(mockService) + } + + @Test + fun `When request successful, it returns success`() = runBlockingTest { + val expected = listOf(response) + coEvery { mockService.getResponses() } returns expected + + repository.getModels() shouldBe expected.toModels() + } + + @Test + fun `When request failed, it returns error`() = runBlockingTest { + coEvery { mockService.getResponses() } throws Throwable() + + shouldThrow { repository.getModels() } + } +} diff --git a/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/UserRepositoryTest.kt b/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/UserRepositoryTest.kt deleted file mode 100644 index 76b8c5a84..000000000 --- a/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/UserRepositoryTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package co.nimblehq.coroutine.data.repository - -import co.nimblehq.coroutine.data.response.UserResponse -import co.nimblehq.coroutine.data.response.toUsers -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.repository.UserRepository -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.matchers.shouldBe -import io.mockk.coEvery -import io.mockk.mockk -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Before -import org.junit.Test - -@ExperimentalCoroutinesApi -class UserRepositoryTest { - - private lateinit var mockService: ApiService - private lateinit var repository: UserRepository - - private val userResponse = UserResponse( - id = 1, - name = "name", - username = "username", - email = "email", - addressResponse = null, - phone = null, - website = null - ) - - @Before - fun setup() { - mockService = mockk() - repository = UserRepositoryImpl(mockService) - } - - @Test - fun `When calling getUsers request successfully, it returns success response`() = runBlockingTest { - coEvery { mockService.getUsers() } returns listOf(userResponse) - - repository.getUsers() shouldBe listOf(userResponse).toUsers() - } - - @Test - fun `When calling getUsers request failed, it returns wrapped error`() = runBlockingTest { - coEvery { mockService.getUsers() } throws Throwable() - - shouldThrow { - repository.getUsers() - } - } -} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt new file mode 100644 index 000000000..6b5d86524 --- /dev/null +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt @@ -0,0 +1,5 @@ +package co.nimblehq.coroutine.domain.model + +data class Model( + val id: Int? +) diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/User.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/User.kt deleted file mode 100644 index 04511ba83..000000000 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/User.kt +++ /dev/null @@ -1,26 +0,0 @@ -package co.nimblehq.coroutine.domain.model - -data class User( - val id: Int?, - val name: String, - val username: String, - val email: String, - val address: Address?, - val phone: String, - val website: String -) { - - data class Address( - val street: String, - val suite: String, - val city: String, - val zipCode: String, - val geo: Geo? - ) { - - data class Geo( - val latitude: String, - val longitude: String - ) - } -} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt new file mode 100644 index 000000000..9b3ed6b32 --- /dev/null +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt @@ -0,0 +1,8 @@ +package co.nimblehq.coroutine.domain.repository + +import co.nimblehq.coroutine.domain.model.Model + +interface Repository { + + suspend fun getModels(): List +} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/UserRepository.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/UserRepository.kt deleted file mode 100644 index dca1dd2ab..000000000 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/UserRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package co.nimblehq.coroutine.domain.repository - -import co.nimblehq.coroutine.domain.model.User - -interface UserRepository { - - suspend fun getUsers(): List -} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCase.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCase.kt deleted file mode 100644 index e71ea9c81..000000000 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCase.kt +++ /dev/null @@ -1,17 +0,0 @@ -package co.nimblehq.coroutine.domain.usecase - -import co.nimblehq.coroutine.domain.model.User -import co.nimblehq.coroutine.domain.repository.UserRepository -import javax.inject.Inject - -class GetUsersUseCase @Inject constructor(private val userRepository: UserRepository) { - - suspend fun execute(): UseCaseResult> { - return try { - val response = userRepository.getUsers() - UseCaseResult.Success(response) - } catch (e: Exception) { - UseCaseResult.Error(e) - } - } -} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt new file mode 100644 index 000000000..42e4bd688 --- /dev/null +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt @@ -0,0 +1,17 @@ +package co.nimblehq.coroutine.domain.usecase + +import co.nimblehq.coroutine.domain.model.Model +import co.nimblehq.coroutine.domain.repository.Repository +import javax.inject.Inject + +class UseCase @Inject constructor(private val repository: Repository) { + + suspend fun execute(): UseCaseResult> { + return try { + val response = repository.getModels() + UseCaseResult.Success(response) + } catch (e: IllegalStateException) { + UseCaseResult.Error(e) + } + } +} diff --git a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCaseTest.kt b/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCaseTest.kt deleted file mode 100644 index 9b46cc64a..000000000 --- a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/GetUsersUseCaseTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -package co.nimblehq.coroutine.domain.usecase - -import co.nimblehq.coroutine.domain.model.User -import co.nimblehq.coroutine.domain.repository.UserRepository -import io.kotest.matchers.shouldBe -import io.mockk.coEvery -import io.mockk.mockk -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Before -import org.junit.Test - -@ExperimentalCoroutinesApi -class GetUsersUseCaseTest { - - private lateinit var mockRepository: UserRepository - private lateinit var usecase: GetUsersUseCase - - private val user = User( - id = 1, - name = "name", - username = "username", - email = "email", - address = null, - phone = "", - website = "" - ) - - @Before - fun setup() { - mockRepository = mockk() - usecase = GetUsersUseCase(mockRepository) - } - - @Test - fun `When calling request successfully, it returns success response`() = runBlockingTest { - val expected = listOf(user) - coEvery { mockRepository.getUsers() } returns expected - - usecase.execute().run { - (this as UseCaseResult.Success).data shouldBe expected - } - } - - @Test - fun `When calling request failed, it returns wrapped error`() = runBlockingTest { - val expected = Exception() - coEvery { mockRepository.getUsers() } throws expected - - usecase.execute().run { - (this as UseCaseResult.Error).exception shouldBe expected - } - } -} diff --git a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt b/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt new file mode 100644 index 000000000..74d906cf1 --- /dev/null +++ b/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt @@ -0,0 +1,46 @@ +package co.nimblehq.coroutine.domain.usecase + +import co.nimblehq.coroutine.domain.model.Model +import co.nimblehq.coroutine.domain.repository.Repository +import io.kotest.matchers.shouldBe +import io.mockk.coEvery +import io.mockk.mockk +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Before +import org.junit.Test + +@ExperimentalCoroutinesApi +class UseCaseTest { + + private lateinit var mockRepository: Repository + private lateinit var usecase: UseCase + + private val model = Model(id = 1) + + @Before + fun setup() { + mockRepository = mockk() + usecase = UseCase(mockRepository) + } + + @Test + fun `When request successful, it returns success`() = runBlockingTest { + val expected = listOf(model) + coEvery { mockRepository.getModels() } returns expected + + usecase.execute().run { + (this as UseCaseResult.Success).data shouldBe expected + } + } + + @Test + fun `When request failed, it returns error`() = runBlockingTest { + val expected = IllegalStateException() + coEvery { mockRepository.getModels() } throws expected + + usecase.execute().run { + (this as UseCaseResult.Error).exception shouldBe expected + } + } +} diff --git a/CoroutineTemplate/settings.gradle.kts b/CoroutineTemplate/settings.gradle.kts index 6f32d6bae..d2f183fcb 100644 --- a/CoroutineTemplate/settings.gradle.kts +++ b/CoroutineTemplate/settings.gradle.kts @@ -1,2 +1 @@ -// FIXME Project build error when using Configurations.Module constants include(":app", ":data", ":domain") From 4b253bb762fab88cae131de86d85c8be891d00c2 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Thu, 21 Jul 2022 13:53:57 +0700 Subject: [PATCH 3/9] [#240] Apply code review changes --- .../ui/screens/compose/composables/HomeScreen.kt | 4 ++-- .../coroutine/ui/screens/compose/theme/Dimension.kt | 2 +- .../nimblehq/coroutine/data/repository/RepositoryImpl.kt | 4 +--- .../co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt | 8 ++++---- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt index 5aebb74ef..0521fe978 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import co.nimblehq.coroutine.model.UiModel -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension.spacingNormal +import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension.SpacingNormal import co.nimblehq.coroutine.ui.screens.compose.theme.Theme import timber.log.Timber @@ -25,7 +25,7 @@ fun HomeScreen( textAlign = TextAlign.Center, modifier = Modifier .wrapContentHeight() - .padding(all = spacingNormal) + .padding(all = SpacingNormal) ) } Timber.d("Result : $uiModels") diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt index 09bc9461a..2f3fce43c 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt @@ -4,5 +4,5 @@ import androidx.compose.ui.unit.dp @Suppress("MagicNumber") object Dimension { - val spacingNormal = 16.dp + val SpacingNormal = 16.dp } diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt index d6b090dba..7d9ef0c97 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt @@ -9,7 +9,5 @@ class RepositoryImpl constructor( private val apiService: ApiService ) : Repository { - override suspend fun getModels(): List { - return apiService.getResponses().toModels() - } + override suspend fun getModels(): List = apiService.getResponses().toModels() } diff --git a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt b/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt index 74d906cf1..7e6dd6bf0 100644 --- a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt +++ b/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt @@ -14,14 +14,14 @@ import org.junit.Test class UseCaseTest { private lateinit var mockRepository: Repository - private lateinit var usecase: UseCase + private lateinit var useCase: UseCase private val model = Model(id = 1) @Before fun setup() { mockRepository = mockk() - usecase = UseCase(mockRepository) + useCase = UseCase(mockRepository) } @Test @@ -29,7 +29,7 @@ class UseCaseTest { val expected = listOf(model) coEvery { mockRepository.getModels() } returns expected - usecase.execute().run { + useCase.execute().run { (this as UseCaseResult.Success).data shouldBe expected } } @@ -39,7 +39,7 @@ class UseCaseTest { val expected = IllegalStateException() coEvery { mockRepository.getModels() } throws expected - usecase.execute().run { + useCase.execute().run { (this as UseCaseResult.Error).exception shouldBe expected } } From 2de3d9c0a87cf35c884d8db6dfe26235cafb7283 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Fri, 22 Jul 2022 18:01:44 +0700 Subject: [PATCH 4/9] [#244] Rename co.nimblehq.coroutine to co.nimblehq.template (package) --- .../app/src/debug/AndroidManifest.xml | 2 +- .../{coroutine => template}/EmptyHiltActivity.kt | 2 +- CoroutineTemplate/app/src/main/AndroidManifest.xml | 2 +- .../java/co/nimblehq/coroutine/lib/TypeAlias.kt | 3 --- .../nimblehq/coroutine/ui/base/NavigationEvent.kt | 3 --- .../CoroutineTemplateApplication.kt | 2 +- .../di/modules/AppModule.kt | 6 +++--- .../di/modules/MoshiModule.kt | 4 ++-- .../di/modules/NavigatorModule.kt | 6 +++--- .../di/modules/OkHttpClientModule.kt | 4 ++-- .../di/modules/RepositoryModule.kt | 8 ++++---- .../di/modules/RetrofitModule.kt | 12 ++++++------ .../di/modules/StorageModule.kt | 6 +++--- .../di/modules/main/MainActivityModule.kt | 2 +- .../extension/ViewModelExt.kt | 2 +- .../java/co/nimblehq/template/lib/TypeAlias.kt | 3 +++ .../{coroutine => template}/model/UiModel.kt | 4 ++-- .../{coroutine => template}/ui/ErrorMapping.kt | 4 ++-- .../ui/base/BaseActivity.kt | 2 +- .../ui/base/BaseComposeFragment.kt | 4 ++-- .../ui/base/BaseComposeFragmentCallbacks.kt | 2 +- .../ui/base/BaseFragment.kt | 6 +++--- .../ui/base/BaseFragmentCallbacks.kt | 2 +- .../ui/base/BaseNavigator.kt | 2 +- .../ui/base/BaseViewModel.kt | 6 +++--- .../nimblehq/template/ui/base/NavigationEvent.kt | 3 +++ .../ui/base/NavigationException.kt | 2 +- .../{coroutine => template}/ui/common/Toaster.kt | 2 +- .../ui/screens/MainActivity.kt | 6 +++--- .../ui/screens/MainNavigator.kt | 10 +++++----- .../ui/screens/MainViewModel.kt | 6 +++--- .../ui/screens/compose/HomeComposeFragment.kt | 12 ++++++------ .../ui/screens/compose/HomeComposeViewModel.kt | 14 +++++++------- .../ui/screens/compose/composables/HomeScreen.kt | 8 ++++---- .../ui/screens/compose/theme/Color.kt | 2 +- .../ui/screens/compose/theme/Dimension.kt | 2 +- .../ui/screens/compose/theme/Theme.kt | 2 +- .../ui/screens/xml/HomeFragment.kt | 12 ++++++------ .../ui/screens/xml/HomeViewModel.kt | 14 +++++++------- .../util/DispatchersProvider.kt | 2 +- .../util/DispatchersProviderImpl.kt | 2 +- .../app/src/main/res/navigation/nav_graph_main.xml | 4 ++-- .../{coroutine => template}/test/TestModules.kt | 6 +++--- .../{coroutine => template}/test/ViewModelExt.kt | 4 ++-- .../{coroutine => template}/ui/BaseFragmentTest.kt | 8 ++++---- .../ui/screens/xml/HomeFragmentTest.kt | 14 +++++++------- .../data/src/main/AndroidManifest.xml | 2 +- .../coroutine/data/repository/RepositoryImpl.kt | 13 ------------- .../template/data/repository/RepositoryImpl.kt | 13 +++++++++++++ .../data/response/Response.kt | 4 ++-- .../data/service/ApiService.kt | 4 ++-- .../data/service/providers/ApiServiceProvider.kt | 4 ++-- .../service/providers/ConverterFactoryProvider.kt | 2 +- .../data/service/providers/MoshiBuilderProvider.kt | 2 +- .../data/service/providers/RetrofitProvider.kt | 2 +- .../data/storage/BaseSharedPreferences.kt | 2 +- .../data/storage/EncryptedSharedPreferences.kt | 2 +- .../data/storage/NormalSharedPreferences.kt | 2 +- .../data/storage/SharedPreferencesExt.kt | 2 +- .../data/repository/RepositoryTest.kt | 10 +++++----- .../co/nimblehq/coroutine/domain/model/Model.kt | 5 ----- .../coroutine/domain/repository/Repository.kt | 8 -------- .../co/nimblehq/template/domain/model/Model.kt | 5 +++++ .../template/domain/repository/Repository.kt | 8 ++++++++ .../domain/usecase/UseCase.kt | 6 +++--- .../domain/usecase/UseCaseResult.kt | 2 +- .../domain/usecase/UseCaseTest.kt | 6 +++--- 67 files changed, 169 insertions(+), 169 deletions(-) rename CoroutineTemplate/app/src/debug/java/co/nimblehq/{coroutine => template}/EmptyHiltActivity.kt (84%) delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/lib/TypeAlias.kt delete mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/CoroutineTemplateApplication.kt (92%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/AppModule.kt (67%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/MoshiModule.kt (73%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/NavigatorModule.kt (66%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/OkHttpClientModule.kt (89%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/RepositoryModule.kt (59%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/RetrofitModule.kt (72%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/StorageModule.kt (84%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/di/modules/main/MainActivityModule.kt (79%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/extension/ViewModelExt.kt (97%) create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/model/UiModel.kt (65%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/ErrorMapping.kt (70%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseActivity.kt (95%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseComposeFragment.kt (95%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseComposeFragmentCallbacks.kt (97%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseFragment.kt (94%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseFragmentCallbacks.kt (98%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseNavigator.kt (98%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/BaseViewModel.kt (91%) create mode 100644 CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/base/NavigationException.kt (88%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/common/Toaster.kt (92%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/MainActivity.kt (72%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/MainNavigator.kt (68%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/MainViewModel.kt (58%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/HomeComposeFragment.kt (73%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/HomeComposeViewModel.kt (72%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/composables/HomeScreen.kt (75%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/theme/Color.kt (75%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/theme/Dimension.kt (67%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/compose/theme/Theme.kt (89%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/xml/HomeFragment.kt (74%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/ui/screens/xml/HomeViewModel.kt (72%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/util/DispatchersProvider.kt (84%) rename CoroutineTemplate/app/src/main/java/co/nimblehq/{coroutine => template}/util/DispatchersProviderImpl.kt (86%) rename CoroutineTemplate/app/src/test/java/co/nimblehq/{coroutine => template}/test/TestModules.kt (74%) rename CoroutineTemplate/app/src/test/java/co/nimblehq/{coroutine => template}/test/ViewModelExt.kt (87%) rename CoroutineTemplate/app/src/test/java/co/nimblehq/{coroutine => template}/ui/BaseFragmentTest.kt (94%) rename CoroutineTemplate/app/src/test/java/co/nimblehq/{coroutine => template}/ui/screens/xml/HomeFragmentTest.kt (74%) delete mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt create mode 100644 CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/response/Response.kt (69%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/service/ApiService.kt (55%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/service/providers/ApiServiceProvider.kt (62%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/service/providers/ConverterFactoryProvider.kt (83%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/service/providers/MoshiBuilderProvider.kt (90%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/service/providers/RetrofitProvider.kt (88%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/storage/BaseSharedPreferences.kt (96%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/storage/EncryptedSharedPreferences.kt (94%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/storage/NormalSharedPreferences.kt (94%) rename CoroutineTemplate/data/src/main/java/co/nimblehq/{coroutine => template}/data/storage/SharedPreferencesExt.kt (81%) rename CoroutineTemplate/data/src/test/java/co/nimblehq/{coroutine => template}/data/repository/RepositoryTest.kt (80%) delete mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt delete mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt create mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt create mode 100644 CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt rename CoroutineTemplate/domain/src/main/java/co/nimblehq/{coroutine => template}/domain/usecase/UseCase.kt (71%) rename CoroutineTemplate/domain/src/main/java/co/nimblehq/{coroutine => template}/domain/usecase/UseCaseResult.kt (80%) rename CoroutineTemplate/domain/src/test/java/co/nimblehq/{coroutine => template}/domain/usecase/UseCaseTest.kt (88%) diff --git a/CoroutineTemplate/app/src/debug/AndroidManifest.xml b/CoroutineTemplate/app/src/debug/AndroidManifest.xml index 67f488a48..b1b4dfc1d 100644 --- a/CoroutineTemplate/app/src/debug/AndroidManifest.xml +++ b/CoroutineTemplate/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="co.nimblehq.template"> + package="co.nimblehq.template"> diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/lib/TypeAlias.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/lib/TypeAlias.kt deleted file mode 100644 index f2a89478a..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/lib/TypeAlias.kt +++ /dev/null @@ -1,3 +0,0 @@ -package co.nimblehq.coroutine.lib - -typealias IsLoading = Boolean diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt deleted file mode 100644 index 0b246cd23..000000000 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationEvent.kt +++ /dev/null @@ -1,3 +0,0 @@ -package co.nimblehq.coroutine.ui.base - -sealed class NavigationEvent diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/CoroutineTemplateApplication.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/CoroutineTemplateApplication.kt similarity index 92% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/CoroutineTemplateApplication.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/CoroutineTemplateApplication.kt index 98483c9f4..fa7027859 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/CoroutineTemplateApplication.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/CoroutineTemplateApplication.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine +package co.nimblehq.template import android.app.Application import dagger.hilt.android.HiltAndroidApp diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/AppModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt similarity index 67% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/AppModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt index e721539cf..2dcf6683c 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/AppModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.util.DispatchersProvider -import co.nimblehq.coroutine.util.DispatchersProviderImpl +import co.nimblehq.template.util.DispatchersProvider +import co.nimblehq.template.util.DispatchersProviderImpl import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/MoshiModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt similarity index 73% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/MoshiModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt index 7883ec780..7a375d613 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/MoshiModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.data.service.providers.MoshiBuilderProvider +import co.nimblehq.template.data.service.providers.MoshiBuilderProvider import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/NavigatorModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt similarity index 66% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/NavigatorModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt index a353edc90..a01418049 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/NavigatorModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.ui.screens.MainNavigator -import co.nimblehq.coroutine.ui.screens.MainNavigatorImpl +import co.nimblehq.template.ui.screens.MainNavigator +import co.nimblehq.template.ui.screens.MainNavigatorImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt similarity index 89% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt index 338d28f6c..c1da0b32e 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.BuildConfig +import co.nimblehq.template.BuildConfig import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt similarity index 59% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt index 03dff62d0..b22f67eee 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RepositoryModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt @@ -1,8 +1,8 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.data.repository.RepositoryImpl -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.repository.Repository +import co.nimblehq.template.data.repository.RepositoryImpl +import co.nimblehq.template.data.service.ApiService +import co.nimblehq.template.domain.repository.Repository import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RetrofitModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt similarity index 72% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RetrofitModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt index bd2f15ecf..d6efd6e5e 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/RetrofitModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt @@ -1,10 +1,10 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules -import co.nimblehq.coroutine.BuildConfig -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.data.service.providers.ApiServiceProvider -import co.nimblehq.coroutine.data.service.providers.ConverterFactoryProvider -import co.nimblehq.coroutine.data.service.providers.RetrofitProvider +import co.nimblehq.template.BuildConfig +import co.nimblehq.template.data.service.ApiService +import co.nimblehq.template.data.service.providers.ApiServiceProvider +import co.nimblehq.template.data.service.providers.ConverterFactoryProvider +import co.nimblehq.template.data.service.providers.RetrofitProvider import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/StorageModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt similarity index 84% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/StorageModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt index 64ec4c4e8..38a2b2c75 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/StorageModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt @@ -1,10 +1,10 @@ -package co.nimblehq.coroutine.di.modules +package co.nimblehq.template.di.modules import android.content.Context import android.content.SharedPreferences import android.preference.PreferenceManager -import co.nimblehq.coroutine.data.storage.EncryptedSharedPreferences -import co.nimblehq.coroutine.data.storage.NormalSharedPreferences +import co.nimblehq.template.data.storage.EncryptedSharedPreferences +import co.nimblehq.template.data.storage.NormalSharedPreferences import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/main/MainActivityModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt similarity index 79% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/main/MainActivityModule.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt index 9d8d70134..7898cbfb2 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/main/MainActivityModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.di.modules.main +package co.nimblehq.template.di.modules.main import dagger.Module import dagger.hilt.InstallIn diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/extension/ViewModelExt.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt similarity index 97% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/extension/ViewModelExt.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt index 279051041..8e66b460a 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/extension/ViewModelExt.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.extension +package co.nimblehq.template.extension import androidx.activity.ComponentActivity import androidx.activity.viewModels diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt new file mode 100644 index 000000000..5044ff2ae --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt @@ -0,0 +1,3 @@ +package co.nimblehq.template.lib + +typealias IsLoading = Boolean diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/model/UiModel.kt similarity index 65% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/model/UiModel.kt index 71985dffd..bb282ac15 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/model/UiModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/model/UiModel.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.model +package co.nimblehq.template.model -import co.nimblehq.coroutine.domain.model.Model +import co.nimblehq.template.domain.model.Model data class UiModel( val id: Int diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt similarity index 70% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt index 65abdc5f2..824d6c0ba 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/ErrorMapping.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.ui +package co.nimblehq.template.ui import android.content.Context -import co.nimblehq.coroutine.R +import co.nimblehq.template.R fun Throwable.userReadableMessage(context: Context): String { return context.getString(R.string.error_generic) diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseActivity.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt similarity index 95% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseActivity.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt index 76e1770e7..328445185 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseActivity.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base import android.os.Bundle import android.view.LayoutInflater diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt similarity index 95% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragment.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt index 90e2f962a..c95fb9714 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragment.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base import android.os.Bundle import android.view.LayoutInflater @@ -11,7 +11,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import co.nimblehq.coroutine.ui.common.Toaster +import co.nimblehq.template.ui.common.Toaster import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragmentCallbacks.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt similarity index 97% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragmentCallbacks.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt index 7a121a554..f82406192 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseComposeFragmentCallbacks.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base /** * An interface provide abstract commitments for the implemented class diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt similarity index 94% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt index 9566f4817..7a376192b 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragment.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base import android.os.Bundle import android.view.LayoutInflater @@ -11,8 +11,8 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.viewbinding.ViewBinding import co.nimblehq.common.extensions.hideSoftKeyboard -import co.nimblehq.coroutine.ui.common.Toaster -import co.nimblehq.coroutine.ui.userReadableMessage +import co.nimblehq.template.ui.common.Toaster +import co.nimblehq.template.ui.userReadableMessage import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragmentCallbacks.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt similarity index 98% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragmentCallbacks.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt index aef405510..9e9488cb0 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseFragmentCallbacks.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base /** * An interface provide abstract commitments for the implemented class diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseNavigator.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt similarity index 98% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseNavigator.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt index 588d8c567..911eebdf7 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseNavigator.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base import android.os.Bundle import android.os.Parcelable diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt similarity index 91% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseViewModel.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt index 054c575c1..ca70ed4a7 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/BaseViewModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt @@ -1,9 +1,9 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import co.nimblehq.coroutine.lib.IsLoading -import co.nimblehq.coroutine.util.DispatchersProvider +import co.nimblehq.template.lib.IsLoading +import co.nimblehq.template.util.DispatchersProvider import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt new file mode 100644 index 000000000..f8438c394 --- /dev/null +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt @@ -0,0 +1,3 @@ +package co.nimblehq.template.ui.base + +sealed class NavigationEvent diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationException.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt similarity index 88% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationException.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt index 97f3a6081..e69b2908e 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/base/NavigationException.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.base +package co.nimblehq.template.ui.base sealed class NavigationException( cause: Throwable? diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/common/Toaster.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt similarity index 92% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/common/Toaster.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt index fbb217552..f65f542c7 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/common/Toaster.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.common +package co.nimblehq.template.ui.common import android.content.Context import android.widget.Toast diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainActivity.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt similarity index 72% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainActivity.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt index 2a1f2e4b3..7e84bc818 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainActivity.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt @@ -1,9 +1,9 @@ -package co.nimblehq.coroutine.ui.screens +package co.nimblehq.template.ui.screens import android.view.LayoutInflater import androidx.activity.viewModels -import co.nimblehq.coroutine.databinding.ActivityMainBinding -import co.nimblehq.coroutine.ui.base.BaseActivity +import co.nimblehq.template.databinding.ActivityMainBinding +import co.nimblehq.template.ui.base.BaseActivity import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt similarity index 68% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt index 88816e8b6..f1d2a0875 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainNavigator.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt @@ -1,10 +1,10 @@ -package co.nimblehq.coroutine.ui.screens +package co.nimblehq.template.ui.screens import androidx.fragment.app.Fragment -import co.nimblehq.coroutine.R -import co.nimblehq.coroutine.ui.base.BaseNavigator -import co.nimblehq.coroutine.ui.base.BaseNavigatorImpl -import co.nimblehq.coroutine.ui.base.NavigationEvent +import co.nimblehq.template.R +import co.nimblehq.template.ui.base.BaseNavigator +import co.nimblehq.template.ui.base.BaseNavigatorImpl +import co.nimblehq.template.ui.base.NavigationEvent import javax.inject.Inject interface MainNavigator : BaseNavigator diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt similarity index 58% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt index e7e87a06f..75ccbc7df 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/MainViewModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.ui.screens +package co.nimblehq.template.ui.screens -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.util.DispatchersProvider +import co.nimblehq.template.ui.base.BaseViewModel +import co.nimblehq.template.util.DispatchersProvider import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt similarity index 73% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt index de53e370d..5215e203b 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeFragment.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt @@ -1,14 +1,14 @@ -package co.nimblehq.coroutine.ui.screens.compose +package co.nimblehq.template.ui.screens.compose import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.res.stringResource -import co.nimblehq.coroutine.R -import co.nimblehq.coroutine.extension.provideViewModels -import co.nimblehq.coroutine.ui.base.BaseComposeFragment -import co.nimblehq.coroutine.ui.screens.MainNavigator -import co.nimblehq.coroutine.ui.screens.compose.composables.HomeScreen +import co.nimblehq.template.R +import co.nimblehq.template.extension.provideViewModels +import co.nimblehq.template.ui.base.BaseComposeFragment +import co.nimblehq.template.ui.screens.MainNavigator +import co.nimblehq.template.ui.screens.compose.composables.HomeScreen import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt similarity index 72% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt index d5fcc3fc2..d83d12201 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/HomeComposeViewModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt @@ -1,11 +1,11 @@ -package co.nimblehq.coroutine.ui.screens.compose +package co.nimblehq.template.ui.screens.compose -import co.nimblehq.coroutine.domain.usecase.UseCase -import co.nimblehq.coroutine.domain.usecase.UseCaseResult -import co.nimblehq.coroutine.model.UiModel -import co.nimblehq.coroutine.model.toUiModels -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.util.DispatchersProvider +import co.nimblehq.template.domain.usecase.UseCase +import co.nimblehq.template.domain.usecase.UseCaseResult +import co.nimblehq.template.model.UiModel +import co.nimblehq.template.model.toUiModels +import co.nimblehq.template.ui.base.BaseViewModel +import co.nimblehq.template.util.DispatchersProvider import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt similarity index 75% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt index 0521fe978..9bf533286 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/composables/HomeScreen.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.screens.compose.composables +package co.nimblehq.template.ui.screens.compose.composables import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight @@ -7,9 +7,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign -import co.nimblehq.coroutine.model.UiModel -import co.nimblehq.coroutine.ui.screens.compose.theme.Dimension.SpacingNormal -import co.nimblehq.coroutine.ui.screens.compose.theme.Theme +import co.nimblehq.template.model.UiModel +import co.nimblehq.template.ui.screens.compose.theme.Dimension.SpacingNormal +import co.nimblehq.template.ui.screens.compose.theme.Theme import timber.log.Timber @Suppress("FunctionNaming") diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt similarity index 75% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt index 63f5f90bc..e6afdccea 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Color.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.screens.compose.theme +package co.nimblehq.template.ui.screens.compose.theme import androidx.compose.ui.graphics.Color diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt similarity index 67% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt index 2f3fce43c..1da748be7 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Dimension.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.screens.compose.theme +package co.nimblehq.template.ui.screens.compose.theme import androidx.compose.ui.unit.dp diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt similarity index 89% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt index 323ac237a..623484903 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/compose/theme/Theme.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui.screens.compose.theme +package co.nimblehq.template.ui.screens.compose.theme import androidx.compose.material.MaterialTheme import androidx.compose.material.lightColors diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt similarity index 74% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt index 85116dac8..e4d1e67d3 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragment.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt @@ -1,12 +1,12 @@ -package co.nimblehq.coroutine.ui.screens.xml +package co.nimblehq.template.ui.screens.xml import android.view.LayoutInflater import android.view.ViewGroup -import co.nimblehq.coroutine.databinding.FragmentHomeBinding -import co.nimblehq.coroutine.extension.provideViewModels -import co.nimblehq.coroutine.model.UiModel -import co.nimblehq.coroutine.ui.base.BaseFragment -import co.nimblehq.coroutine.ui.screens.MainNavigator +import co.nimblehq.template.databinding.FragmentHomeBinding +import co.nimblehq.template.extension.provideViewModels +import co.nimblehq.template.model.UiModel +import co.nimblehq.template.ui.base.BaseFragment +import co.nimblehq.template.ui.screens.MainNavigator import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber import javax.inject.Inject diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt similarity index 72% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt index 1009f1e30..c0d598ef5 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/ui/screens/xml/HomeViewModel.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt @@ -1,11 +1,11 @@ -package co.nimblehq.coroutine.ui.screens.xml +package co.nimblehq.template.ui.screens.xml -import co.nimblehq.coroutine.domain.usecase.UseCase -import co.nimblehq.coroutine.domain.usecase.UseCaseResult -import co.nimblehq.coroutine.model.UiModel -import co.nimblehq.coroutine.model.toUiModels -import co.nimblehq.coroutine.ui.base.BaseViewModel -import co.nimblehq.coroutine.util.DispatchersProvider +import co.nimblehq.template.domain.usecase.UseCase +import co.nimblehq.template.domain.usecase.UseCaseResult +import co.nimblehq.template.model.UiModel +import co.nimblehq.template.model.toUiModels +import co.nimblehq.template.ui.base.BaseViewModel +import co.nimblehq.template.util.DispatchersProvider import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProvider.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt similarity index 84% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProvider.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt index 2c71b0dbe..cf2385523 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProvider.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.util +package co.nimblehq.template.util import kotlinx.coroutines.CoroutineDispatcher diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProviderImpl.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt similarity index 86% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProviderImpl.kt rename to CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt index d5ab5e6c1..a4565e662 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/util/DispatchersProviderImpl.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.util +package co.nimblehq.template.util import kotlinx.coroutines.Dispatchers diff --git a/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml b/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml index 152e1aeac..848398dbf 100644 --- a/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml +++ b/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml @@ -7,11 +7,11 @@ + android:name="co.nimblehq.template.ui.screens.compose.HomeComposeFragment" /> diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/TestModules.kt b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/TestModules.kt similarity index 74% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/TestModules.kt rename to CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/TestModules.kt index 2d11d151d..162531e62 100644 --- a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/TestModules.kt +++ b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/TestModules.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.test +package co.nimblehq.template.test -import co.nimblehq.coroutine.di.modules.NavigatorModule -import co.nimblehq.coroutine.ui.screens.MainNavigator +import co.nimblehq.template.di.modules.NavigatorModule +import co.nimblehq.template.ui.screens.MainNavigator import dagger.Module import dagger.Provides import dagger.hilt.android.components.FragmentComponent diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/ViewModelExt.kt b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt similarity index 87% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/ViewModelExt.kt rename to CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt index 8bfa67e84..2910da310 100644 --- a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/test/ViewModelExt.kt +++ b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt @@ -1,8 +1,8 @@ -package co.nimblehq.coroutine.test +package co.nimblehq.template.test import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModel -import co.nimblehq.coroutine.extension.OverridableLazy +import co.nimblehq.template.extension.OverridableLazy import kotlin.reflect.KProperty1 import kotlin.reflect.full.memberProperties import kotlin.reflect.jvm.isAccessible diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/BaseFragmentTest.kt b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt similarity index 94% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/BaseFragmentTest.kt rename to CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt index bec2e0aba..2857419a6 100644 --- a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/BaseFragmentTest.kt +++ b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.ui +package co.nimblehq.template.ui import android.content.ComponentName import android.content.Intent @@ -9,9 +9,9 @@ import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.viewbinding.ViewBinding -import co.nimblehq.coroutine.EmptyHiltActivity -import co.nimblehq.coroutine.R -import co.nimblehq.coroutine.ui.base.BaseFragment +import co.nimblehq.template.EmptyHiltActivity +import co.nimblehq.template.R +import co.nimblehq.template.ui.base.BaseFragment import dagger.hilt.android.testing.* import org.junit.runner.RunWith diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt similarity index 74% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt rename to CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt index 0879ca164..7d2ae22f0 100644 --- a/CoroutineTemplate/app/src/test/java/co/nimblehq/coroutine/ui/screens/xml/HomeFragmentTest.kt +++ b/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt @@ -1,11 +1,11 @@ -package co.nimblehq.coroutine.ui.screens.xml +package co.nimblehq.template.ui.screens.xml -import co.nimblehq.coroutine.R -import co.nimblehq.coroutine.databinding.FragmentHomeBinding -import co.nimblehq.coroutine.test.TestNavigatorModule.mockMainNavigator -import co.nimblehq.coroutine.test.getPrivateProperty -import co.nimblehq.coroutine.test.replace -import co.nimblehq.coroutine.ui.BaseFragmentTest +import co.nimblehq.template.R +import co.nimblehq.template.databinding.FragmentHomeBinding +import co.nimblehq.template.test.TestNavigatorModule.mockMainNavigator +import co.nimblehq.template.test.getPrivateProperty +import co.nimblehq.template.test.replace +import co.nimblehq.template.ui.BaseFragmentTest import dagger.hilt.android.testing.* import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe diff --git a/CoroutineTemplate/data/src/main/AndroidManifest.xml b/CoroutineTemplate/data/src/main/AndroidManifest.xml index 729863ae3..dbba6522f 100644 --- a/CoroutineTemplate/data/src/main/AndroidManifest.xml +++ b/CoroutineTemplate/data/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ - + diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt deleted file mode 100644 index 7d9ef0c97..000000000 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/repository/RepositoryImpl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package co.nimblehq.coroutine.data.repository - -import co.nimblehq.coroutine.data.response.toModels -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.model.Model -import co.nimblehq.coroutine.domain.repository.Repository - -class RepositoryImpl constructor( - private val apiService: ApiService -) : Repository { - - override suspend fun getModels(): List = apiService.getResponses().toModels() -} diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt new file mode 100644 index 000000000..c435b47e6 --- /dev/null +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt @@ -0,0 +1,13 @@ +package co.nimblehq.template.data.repository + +import co.nimblehq.template.data.response.toModels +import co.nimblehq.template.data.service.ApiService +import co.nimblehq.template.domain.model.Model +import co.nimblehq.template.domain.repository.Repository + +class RepositoryImpl constructor( + private val apiService: ApiService +) : Repository { + + override suspend fun getModels(): List = apiService.getResponses().toModels() +} diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/response/Response.kt similarity index 69% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/response/Response.kt index 6484bd63c..6a86859ef 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/response/Response.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/response/Response.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.data.response +package co.nimblehq.template.data.response -import co.nimblehq.coroutine.domain.model.Model +import co.nimblehq.template.domain.model.Model import com.squareup.moshi.Json data class Response( diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt similarity index 55% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt index b56e5d19a..39227eb22 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/ApiService.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.data.service +package co.nimblehq.template.data.service -import co.nimblehq.coroutine.data.response.Response +import co.nimblehq.template.data.response.Response import retrofit2.http.GET interface ApiService { diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ApiServiceProvider.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt similarity index 62% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ApiServiceProvider.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt index ac242491f..26b9df515 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ApiServiceProvider.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt @@ -1,6 +1,6 @@ -package co.nimblehq.coroutine.data.service.providers +package co.nimblehq.template.data.service.providers -import co.nimblehq.coroutine.data.service.ApiService +import co.nimblehq.template.data.service.ApiService import retrofit2.Retrofit object ApiServiceProvider { diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ConverterFactoryProvider.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt similarity index 83% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ConverterFactoryProvider.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt index 1abdb4f36..f77262d6a 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/ConverterFactoryProvider.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.service.providers +package co.nimblehq.template.data.service.providers import com.squareup.moshi.Moshi import retrofit2.Converter diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/MoshiBuilderProvider.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt similarity index 90% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/MoshiBuilderProvider.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt index d7344087d..83f667fb8 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/MoshiBuilderProvider.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.service.providers +package co.nimblehq.template.data.service.providers import com.squareup.moshi.Moshi import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/RetrofitProvider.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt similarity index 88% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/RetrofitProvider.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt index 8a0cadf6d..cb3dc8082 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/service/providers/RetrofitProvider.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.service.providers +package co.nimblehq.template.data.service.providers import okhttp3.OkHttpClient import retrofit2.Converter diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/BaseSharedPreferences.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt similarity index 96% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/BaseSharedPreferences.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt index aa5157582..0e36dfd02 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/BaseSharedPreferences.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.storage +package co.nimblehq.template.data.storage import android.content.SharedPreferences diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/EncryptedSharedPreferences.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt similarity index 94% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/EncryptedSharedPreferences.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt index febcaf680..9b9233629 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/EncryptedSharedPreferences.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.storage +package co.nimblehq.template.data.storage import android.content.Context import androidx.security.crypto.EncryptedSharedPreferences diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/NormalSharedPreferences.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt similarity index 94% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/NormalSharedPreferences.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt index d615e4933..0c89eafd6 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/NormalSharedPreferences.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.storage +package co.nimblehq.template.data.storage import android.content.Context import android.content.SharedPreferences diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/SharedPreferencesExt.kt b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt similarity index 81% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/SharedPreferencesExt.kt rename to CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt index 0989c1b5c..f517f1078 100644 --- a/CoroutineTemplate/data/src/main/java/co/nimblehq/coroutine/data/storage/SharedPreferencesExt.kt +++ b/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.data.storage +package co.nimblehq.template.data.storage import android.content.SharedPreferences diff --git a/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt b/CoroutineTemplate/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt similarity index 80% rename from CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt rename to CoroutineTemplate/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt index 340269167..65501cba2 100644 --- a/CoroutineTemplate/data/src/test/java/co/nimblehq/coroutine/data/repository/RepositoryTest.kt +++ b/CoroutineTemplate/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt @@ -1,9 +1,9 @@ -package co.nimblehq.coroutine.data.repository +package co.nimblehq.template.data.repository -import co.nimblehq.coroutine.data.response.Response -import co.nimblehq.coroutine.data.response.toModels -import co.nimblehq.coroutine.data.service.ApiService -import co.nimblehq.coroutine.domain.repository.Repository +import co.nimblehq.template.data.response.Response +import co.nimblehq.template.data.response.toModels +import co.nimblehq.template.data.service.ApiService +import co.nimblehq.template.domain.repository.Repository import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe import io.mockk.coEvery diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt deleted file mode 100644 index 6b5d86524..000000000 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/model/Model.kt +++ /dev/null @@ -1,5 +0,0 @@ -package co.nimblehq.coroutine.domain.model - -data class Model( - val id: Int? -) diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt deleted file mode 100644 index 9b3ed6b32..000000000 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/repository/Repository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package co.nimblehq.coroutine.domain.repository - -import co.nimblehq.coroutine.domain.model.Model - -interface Repository { - - suspend fun getModels(): List -} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt new file mode 100644 index 000000000..e901c5c12 --- /dev/null +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt @@ -0,0 +1,5 @@ +package co.nimblehq.template.domain.model + +data class Model( + val id: Int? +) diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt new file mode 100644 index 000000000..4fd30d8b6 --- /dev/null +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt @@ -0,0 +1,8 @@ +package co.nimblehq.template.domain.repository + +import co.nimblehq.template.domain.model.Model + +interface Repository { + + suspend fun getModels(): List +} diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt similarity index 71% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt rename to CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt index 42e4bd688..36ece0c9e 100644 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCase.kt +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.domain.usecase +package co.nimblehq.template.domain.usecase -import co.nimblehq.coroutine.domain.model.Model -import co.nimblehq.coroutine.domain.repository.Repository +import co.nimblehq.template.domain.model.Model +import co.nimblehq.template.domain.repository.Repository import javax.inject.Inject class UseCase @Inject constructor(private val repository: Repository) { diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCaseResult.kt b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt similarity index 80% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCaseResult.kt rename to CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt index 733326f47..3b102d98f 100644 --- a/CoroutineTemplate/domain/src/main/java/co/nimblehq/coroutine/domain/usecase/UseCaseResult.kt +++ b/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt @@ -1,4 +1,4 @@ -package co.nimblehq.coroutine.domain.usecase +package co.nimblehq.template.domain.usecase sealed class UseCaseResult { class Success(val data: T) : UseCaseResult() diff --git a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt b/CoroutineTemplate/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt similarity index 88% rename from CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt rename to CoroutineTemplate/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt index 7e6dd6bf0..dbf3d966e 100644 --- a/CoroutineTemplate/domain/src/test/java/co/nimblehq/coroutine/domain/usecase/UseCaseTest.kt +++ b/CoroutineTemplate/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt @@ -1,7 +1,7 @@ -package co.nimblehq.coroutine.domain.usecase +package co.nimblehq.template.domain.usecase -import co.nimblehq.coroutine.domain.model.Model -import co.nimblehq.coroutine.domain.repository.Repository +import co.nimblehq.template.domain.model.Model +import co.nimblehq.template.domain.repository.Repository import io.kotest.matchers.shouldBe import io.mockk.coEvery import io.mockk.mockk From 8397a45412e142a02bbad44893435c749079b7d2 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Fri, 22 Jul 2022 18:02:43 +0700 Subject: [PATCH 5/9] [#244] Rename CoroutineTemplateApplication to TemplateApplication (application class) --- CoroutineTemplate/app/src/main/AndroidManifest.xml | 2 +- .../{CoroutineTemplateApplication.kt => TemplateApplication.kt} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename CoroutineTemplate/app/src/main/java/co/nimblehq/template/{CoroutineTemplateApplication.kt => TemplateApplication.kt} (87%) diff --git a/CoroutineTemplate/app/src/main/AndroidManifest.xml b/CoroutineTemplate/app/src/main/AndroidManifest.xml index 025a64126..0d4581ad2 100644 --- a/CoroutineTemplate/app/src/main/AndroidManifest.xml +++ b/CoroutineTemplate/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ Date: Fri, 22 Jul 2022 18:03:41 +0700 Subject: [PATCH 6/9] [#244] Rename "Coroutine Template" to "Template" (strings.xml) --- CoroutineTemplate/app/src/main/res/values/strings.xml | 2 +- CoroutineTemplate/app/src/staging/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CoroutineTemplate/app/src/main/res/values/strings.xml b/CoroutineTemplate/app/src/main/res/values/strings.xml index 0b4738759..1096d61cb 100644 --- a/CoroutineTemplate/app/src/main/res/values/strings.xml +++ b/CoroutineTemplate/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Coroutine Template + Template Unexpected error diff --git a/CoroutineTemplate/app/src/staging/res/values/strings.xml b/CoroutineTemplate/app/src/staging/res/values/strings.xml index 5303e3d32..6bd476455 100644 --- a/CoroutineTemplate/app/src/staging/res/values/strings.xml +++ b/CoroutineTemplate/app/src/staging/res/values/strings.xml @@ -1,4 +1,4 @@ - Coroutine Template - Staging + Template - Staging From 10d2d4c8a6590eb00c5b305682f3c684e5f06971 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Fri, 22 Jul 2022 18:07:01 +0700 Subject: [PATCH 7/9] [#244] Rename CoroutineTemplate to template inside workflows, documentation, ... --- .github/workflows/review_pull_request.yml | 12 +++++------ .../workflows/run_detekt_and_unit_tests.yml | 20 +++++++++---------- .../workflows/verify_newproject_script.yml | 2 +- .gitignore | 2 +- CoroutineTemplate/README.md | 4 ++-- CoroutineTemplate/app/build.gradle.kts | 2 +- .../java/plugins/jacoco-report.gradle.kts | 4 ++-- Dangerfile | 6 +++--- README.md | 4 ++-- scripts/new_project.kts | 8 ++++---- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/review_pull_request.yml b/.github/workflows/review_pull_request.yml index f3a10be29..b9c8bcb0d 100644 --- a/.github/workflows/review_pull_request.yml +++ b/.github/workflows/review_pull_request.yml @@ -29,16 +29,16 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: Run Detekt on CoroutineTemplate - working-directory: ./CoroutineTemplate + - name: Run Detekt on template + working-directory: ./template run: ./gradlew detekt - - name: Run Android Lint on CoroutineTemplate - working-directory: ./CoroutineTemplate + - name: Run Android Lint on template + working-directory: ./template run: ./gradlew lint - - name: Run unit tests and Jacoco on CoroutineTemplate - working-directory: ./CoroutineTemplate + - name: Run unit tests and Jacoco on template + working-directory: ./template run: ./gradlew jacocoTestReport - name: Set up Ruby diff --git a/.github/workflows/run_detekt_and_unit_tests.yml b/.github/workflows/run_detekt_and_unit_tests.yml index 29f78f30c..5dcc405e4 100644 --- a/.github/workflows/run_detekt_and_unit_tests.yml +++ b/.github/workflows/run_detekt_and_unit_tests.yml @@ -27,22 +27,22 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: Run Detekt on CoroutineTemplate - working-directory: ./CoroutineTemplate + - name: Run Detekt on template + working-directory: ./template run: ./gradlew detekt - - name: Archive Detekt reports on CoroutineTemplate + - name: Archive Detekt reports on template uses: actions/upload-artifact@v2 with: - name: DetektReportsCoroutine - path: CoroutineTemplate/build/reports/detekt/ + name: DetektReportsTemplate + path: template/build/reports/detekt/ - - name: Run unit tests and Jacoco on CoroutineTemplate - working-directory: ./CoroutineTemplate + - name: Run unit tests and Jacoco on template + working-directory: ./template run: ./gradlew jacocoTestReport - - name: Archive code coverage reports on CoroutineTemplate + - name: Archive code coverage reports on template uses: actions/upload-artifact@v2 with: - name: CodeCoverageReportsCoroutine - path: CoroutineTemplate/app/build/reports/jacoco/jacocoTestReport/ + name: CodeCoverageReportsTemplate + path: template/app/build/reports/jacoco/jacocoTestReport/ diff --git a/.github/workflows/verify_newproject_script.yml b/.github/workflows/verify_newproject_script.yml index 247bd29f7..b96891cf7 100644 --- a/.github/workflows/verify_newproject_script.yml +++ b/.github/workflows/verify_newproject_script.yml @@ -38,6 +38,6 @@ jobs: sdk install kscript 4.0.3 echo $PATH >> $GITHUB_PATH - - name: Verify generating new project from CoroutineTemplate + - name: Verify generating new project from template working-directory: scripts run: kscript new_project.kts package-name=co.myproject.example app-name="My Project" diff --git a/.gitignore b/.gitignore index 5be5842aa..ee48d0338 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.iml .idea .gradle -/CoroutineTemplate/local.properties +/template/local.properties /RxJavaTemplate[DEPRECATED]/local.properties .DS_Store build/ diff --git a/CoroutineTemplate/README.md b/CoroutineTemplate/README.md index 628857310..2a0a6d11e 100644 --- a/CoroutineTemplate/README.md +++ b/CoroutineTemplate/README.md @@ -1,4 +1,4 @@ -# Android Templates: Coroutine +# Android Templates - Our optimized Android templates used in our android projects @@ -48,4 +48,4 @@ Report is located at: `./app/build/reports/jacoco/` For `release` builds, we need to provide release keystore and signing properties: - Put the `release.keystore` file at root `config` folder. -- Put keystore signing properties in [signing.properties](https://github.com/nimblehq/android-templates/blob/develop/CoroutineTemplate/signing.properties). +- Put keystore signing properties in [signing.properties](https://github.com/nimblehq/android-templates/blob/develop/template/signing.properties). diff --git a/CoroutineTemplate/app/build.gradle.kts b/CoroutineTemplate/app/build.gradle.kts index 4e3e10040..d5ed08c67 100644 --- a/CoroutineTemplate/app/build.gradle.kts +++ b/CoroutineTemplate/app/build.gradle.kts @@ -33,7 +33,7 @@ android { compileSdk = Versions.ANDROID_COMPILE_SDK_VERSION defaultConfig { - applicationId = "co.nimblehq.coroutine" + applicationId = "co.nimblehq.template" minSdk = Versions.ANDROID_MIN_SDK_VERSION targetSdk = Versions.ANDROID_TARGET_SDK_VERSION versionCode = Versions.ANDROID_VERSION_CODE diff --git a/CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts b/CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts index d4e32fb88..cd5b6da19 100644 --- a/CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts +++ b/CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts @@ -40,8 +40,8 @@ val packagesExcluded = setOf( "**/com/bumptech/glide", "**/dagger/hilt/internal", "**/hilt_aggregated_deps", - "**/co/nimblehq/coroutine/databinding/**", - "**/co/nimblehq/coroutine/di/**" + "**/co/nimblehq/template/databinding/**", + "**/co/nimblehq/template/di/**" ) val fileFilter = fileGenerated + packagesExcluded diff --git a/Dangerfile b/Dangerfile index 11e20dbc4..3e44eae40 100644 --- a/Dangerfile +++ b/Dangerfile @@ -29,9 +29,9 @@ Dir[lint_dir].each do |file_name| android_lint.lint(inline_mode: true) end -# Show Danger test coverage report from Jacoco for CoroutineTemplate -jacoco_dir = "CoroutineTemplate/**/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml" -markdown "## CoroutineTemplate Jacoco report:" +# Show Danger test coverage report from Jacoco for Template +jacoco_dir = "template/**/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml" +markdown "## Template Jacoco report:" Dir[jacoco_dir].each do |file_name| # Report coverage of modified files, warn if total project coverage is under 80% # or if any modified file's coverage is under 95% diff --git a/README.md b/README.md index 9adcaeaa2..45c59cc26 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ --- -Our Android template: **[CoroutineTemplate](https://github.com/nimblehq/android-templates/tree/develop/CoroutineTemplate)** +Our Android template: **[Template](https://github.com/nimblehq/android-templates/tree/develop/template)** ## Setup @@ -23,7 +23,7 @@ Our Android template: **[CoroutineTemplate](https://github.com/nimblehq/android- Example: `kscript new_project.kts package-name=co.myproject.example app-name="My Project"` -4. Update `android_version_code` and `android_version_name` in `CoroutineTemplate/build.gradle` +4. Update `android_version_code` and `android_version_name` in `template/build.gradle` ## About diff --git a/scripts/new_project.kts b/scripts/new_project.kts index 981186fcc..0546bcfc5 100644 --- a/scripts/new_project.kts +++ b/scripts/new_project.kts @@ -8,10 +8,10 @@ object NewProject { private const val KEY_PACKAGE_NAME = "package-name" private const val MINUS_SEPARATOR = "-" private const val SPACE_SEPARATOR = " " - private const val TEMPLATE_APP_NAME = "Coroutine Template" - private const val TEMPLATE_APPLICATION_CLASS_NAME = "CoroutineTemplateApplication" - private const val TEMPLATE_FOLDER_NAME = "CoroutineTemplate" - private const val TEMPLATE_PACKAGE_NAME = "co.nimblehq.coroutine" + private const val TEMPLATE_APP_NAME = "Template" + private const val TEMPLATE_APPLICATION_CLASS_NAME = "TemplateApplication" + private const val TEMPLATE_FOLDER_NAME = "template" + private const val TEMPLATE_PACKAGE_NAME = "co.nimblehq.template" private const val PATTERN_APP = "^([A-Z][a-zA-Z0-9\\s]*)|([a-z][a-z0-9-]*)$" private const val PATTERN_PACKAGE = "^[a-z]+(\\.[a-z][a-z0-9]*)+$" From beca798a3520c867ccca02b7838c160fd531a2f2 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Fri, 22 Jul 2022 18:08:09 +0700 Subject: [PATCH 8/9] [#244] Rename CoroutineTemplate folder to template (main folder) --- {CoroutineTemplate => template}/.gitignore | 0 {CoroutineTemplate => template}/README.md | 0 {CoroutineTemplate => template}/app/.gitignore | 0 .../app/build.gradle.kts | 0 .../app/proguard-rules.pro | 0 .../app/src/debug/AndroidManifest.xml | 0 .../java/co/nimblehq/template/EmptyHiltActivity.kt | 0 .../app/src/main/AndroidManifest.xml | 0 .../co/nimblehq/template/TemplateApplication.kt | 0 .../co/nimblehq/template/di/modules/AppModule.kt | 0 .../co/nimblehq/template/di/modules/MoshiModule.kt | 0 .../nimblehq/template/di/modules/NavigatorModule.kt | 0 .../template/di/modules/OkHttpClientModule.kt | 0 .../template/di/modules/RepositoryModule.kt | 0 .../nimblehq/template/di/modules/RetrofitModule.kt | 0 .../nimblehq/template/di/modules/StorageModule.kt | 0 .../template/di/modules/main/MainActivityModule.kt | 0 .../co/nimblehq/template/extension/ViewModelExt.kt | 0 .../main/java/co/nimblehq/template/lib/TypeAlias.kt | 0 .../main/java/co/nimblehq/template/model/UiModel.kt | 0 .../java/co/nimblehq/template/ui/ErrorMapping.kt | 0 .../co/nimblehq/template/ui/base/BaseActivity.kt | 0 .../template/ui/base/BaseComposeFragment.kt | 0 .../ui/base/BaseComposeFragmentCallbacks.kt | 0 .../co/nimblehq/template/ui/base/BaseFragment.kt | 0 .../template/ui/base/BaseFragmentCallbacks.kt | 0 .../co/nimblehq/template/ui/base/BaseNavigator.kt | 0 .../co/nimblehq/template/ui/base/BaseViewModel.kt | 0 .../co/nimblehq/template/ui/base/NavigationEvent.kt | 0 .../template/ui/base/NavigationException.kt | 0 .../java/co/nimblehq/template/ui/common/Toaster.kt | 0 .../co/nimblehq/template/ui/screens/MainActivity.kt | 0 .../nimblehq/template/ui/screens/MainNavigator.kt | 0 .../nimblehq/template/ui/screens/MainViewModel.kt | 0 .../ui/screens/compose/HomeComposeFragment.kt | 0 .../ui/screens/compose/HomeComposeViewModel.kt | 0 .../ui/screens/compose/composables/HomeScreen.kt | 0 .../template/ui/screens/compose/theme/Color.kt | 0 .../template/ui/screens/compose/theme/Dimension.kt | 0 .../template/ui/screens/compose/theme/Theme.kt | 0 .../template/ui/screens/xml/HomeFragment.kt | 0 .../template/ui/screens/xml/HomeViewModel.kt | 0 .../nimblehq/template/util/DispatchersProvider.kt | 0 .../template/util/DispatchersProviderImpl.kt | 0 .../res/drawable-v24/ic_launcher_foreground.xml | 0 .../main/res/drawable/ic_launcher_background.xml | 0 .../app/src/main/res/layout/activity_main.xml | 0 .../app/src/main/res/layout/fragment_home.xml | 0 .../src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-hdpi/ic_launcher_round.png | Bin .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher_round.png | Bin .../app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher_round.png | Bin .../app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../app/src/main/res/navigation/nav_graph_main.xml | 0 .../app/src/main/res/values/colors.xml | 0 .../app/src/main/res/values/dimens.xml | 0 .../app/src/main/res/values/strings.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../src/main/res/xml/network_security_config.xml | 0 .../app/src/staging/res/values/strings.xml | 0 .../src/staging/res/xml/network_security_config.xml | 0 .../java/co/nimblehq/template/test/TestModules.kt | 0 .../java/co/nimblehq/template/test/ViewModelExt.kt | 0 .../co/nimblehq/template/ui/BaseFragmentTest.kt | 0 .../template/ui/screens/xml/HomeFragmentTest.kt | 0 .../app/src/test/resources/robolectric.properties | 0 {CoroutineTemplate => template}/build.gradle.kts | 0 .../buildSrc/build.gradle.kts | 0 .../buildSrc/src/main/java/Configurations.kt | 0 .../buildSrc/src/main/java/FileExt.kt | 0 .../buildSrc/src/main/java/Versions.kt | 0 .../src/main/java/plugins/jacoco-report.gradle.kts | 0 .../config/debug.keystore | Bin {CoroutineTemplate => template}/data/.gitignore | 0 .../data/build.gradle.kts | 0 .../data/proguard-rules.pro | 0 .../data/src/main/AndroidManifest.xml | 0 .../template/data/repository/RepositoryImpl.kt | 0 .../co/nimblehq/template/data/response/Response.kt | 0 .../co/nimblehq/template/data/service/ApiService.kt | 0 .../data/service/providers/ApiServiceProvider.kt | 0 .../service/providers/ConverterFactoryProvider.kt | 0 .../data/service/providers/MoshiBuilderProvider.kt | 0 .../data/service/providers/RetrofitProvider.kt | 0 .../template/data/storage/BaseSharedPreferences.kt | 0 .../data/storage/EncryptedSharedPreferences.kt | 0 .../data/storage/NormalSharedPreferences.kt | 0 .../template/data/storage/SharedPreferencesExt.kt | 0 .../template/data/repository/RepositoryTest.kt | 0 {CoroutineTemplate => template}/detekt-config.yml | 0 {CoroutineTemplate => template}/domain/.gitignore | 0 .../domain/build.gradle.kts | 0 .../java/co/nimblehq/template/domain/model/Model.kt | 0 .../template/domain/repository/Repository.kt | 0 .../co/nimblehq/template/domain/usecase/UseCase.kt | 0 .../template/domain/usecase/UseCaseResult.kt | 0 .../nimblehq/template/domain/usecase/UseCaseTest.kt | 0 {CoroutineTemplate => template}/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {CoroutineTemplate => template}/gradlew | 0 {CoroutineTemplate => template}/gradlew.bat | 0 {CoroutineTemplate => template}/settings.gradle.kts | 0 {CoroutineTemplate => template}/signing.properties | 0 111 files changed, 0 insertions(+), 0 deletions(-) rename {CoroutineTemplate => template}/.gitignore (100%) rename {CoroutineTemplate => template}/README.md (100%) rename {CoroutineTemplate => template}/app/.gitignore (100%) rename {CoroutineTemplate => template}/app/build.gradle.kts (100%) rename {CoroutineTemplate => template}/app/proguard-rules.pro (100%) rename {CoroutineTemplate => template}/app/src/debug/AndroidManifest.xml (100%) rename {CoroutineTemplate => template}/app/src/debug/java/co/nimblehq/template/EmptyHiltActivity.kt (100%) rename {CoroutineTemplate => template}/app/src/main/AndroidManifest.xml (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/TemplateApplication.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/model/UiModel.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt (100%) rename {CoroutineTemplate => template}/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt (100%) rename {CoroutineTemplate => template}/app/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/drawable/ic_launcher_background.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/layout/activity_main.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/layout/fragment_home.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {CoroutineTemplate => template}/app/src/main/res/navigation/nav_graph_main.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/values/colors.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/values/dimens.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/values/strings.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/values/styles.xml (100%) rename {CoroutineTemplate => template}/app/src/main/res/xml/network_security_config.xml (100%) rename {CoroutineTemplate => template}/app/src/staging/res/values/strings.xml (100%) rename {CoroutineTemplate => template}/app/src/staging/res/xml/network_security_config.xml (100%) rename {CoroutineTemplate => template}/app/src/test/java/co/nimblehq/template/test/TestModules.kt (100%) rename {CoroutineTemplate => template}/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt (100%) rename {CoroutineTemplate => template}/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt (100%) rename {CoroutineTemplate => template}/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt (100%) rename {CoroutineTemplate => template}/app/src/test/resources/robolectric.properties (100%) rename {CoroutineTemplate => template}/build.gradle.kts (100%) rename {CoroutineTemplate => template}/buildSrc/build.gradle.kts (100%) rename {CoroutineTemplate => template}/buildSrc/src/main/java/Configurations.kt (100%) rename {CoroutineTemplate => template}/buildSrc/src/main/java/FileExt.kt (100%) rename {CoroutineTemplate => template}/buildSrc/src/main/java/Versions.kt (100%) rename {CoroutineTemplate => template}/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts (100%) rename {CoroutineTemplate => template}/config/debug.keystore (100%) rename {CoroutineTemplate => template}/data/.gitignore (100%) rename {CoroutineTemplate => template}/data/build.gradle.kts (100%) rename {CoroutineTemplate => template}/data/proguard-rules.pro (100%) rename {CoroutineTemplate => template}/data/src/main/AndroidManifest.xml (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/response/Response.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt (100%) rename {CoroutineTemplate => template}/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt (100%) rename {CoroutineTemplate => template}/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt (100%) rename {CoroutineTemplate => template}/detekt-config.yml (100%) rename {CoroutineTemplate => template}/domain/.gitignore (100%) rename {CoroutineTemplate => template}/domain/build.gradle.kts (100%) rename {CoroutineTemplate => template}/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt (100%) rename {CoroutineTemplate => template}/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt (100%) rename {CoroutineTemplate => template}/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt (100%) rename {CoroutineTemplate => template}/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt (100%) rename {CoroutineTemplate => template}/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt (100%) rename {CoroutineTemplate => template}/gradle.properties (100%) rename {CoroutineTemplate => template}/gradle/wrapper/gradle-wrapper.jar (100%) rename {CoroutineTemplate => template}/gradle/wrapper/gradle-wrapper.properties (100%) rename {CoroutineTemplate => template}/gradlew (100%) rename {CoroutineTemplate => template}/gradlew.bat (100%) rename {CoroutineTemplate => template}/settings.gradle.kts (100%) rename {CoroutineTemplate => template}/signing.properties (100%) diff --git a/CoroutineTemplate/.gitignore b/template/.gitignore similarity index 100% rename from CoroutineTemplate/.gitignore rename to template/.gitignore diff --git a/CoroutineTemplate/README.md b/template/README.md similarity index 100% rename from CoroutineTemplate/README.md rename to template/README.md diff --git a/CoroutineTemplate/app/.gitignore b/template/app/.gitignore similarity index 100% rename from CoroutineTemplate/app/.gitignore rename to template/app/.gitignore diff --git a/CoroutineTemplate/app/build.gradle.kts b/template/app/build.gradle.kts similarity index 100% rename from CoroutineTemplate/app/build.gradle.kts rename to template/app/build.gradle.kts diff --git a/CoroutineTemplate/app/proguard-rules.pro b/template/app/proguard-rules.pro similarity index 100% rename from CoroutineTemplate/app/proguard-rules.pro rename to template/app/proguard-rules.pro diff --git a/CoroutineTemplate/app/src/debug/AndroidManifest.xml b/template/app/src/debug/AndroidManifest.xml similarity index 100% rename from CoroutineTemplate/app/src/debug/AndroidManifest.xml rename to template/app/src/debug/AndroidManifest.xml diff --git a/CoroutineTemplate/app/src/debug/java/co/nimblehq/template/EmptyHiltActivity.kt b/template/app/src/debug/java/co/nimblehq/template/EmptyHiltActivity.kt similarity index 100% rename from CoroutineTemplate/app/src/debug/java/co/nimblehq/template/EmptyHiltActivity.kt rename to template/app/src/debug/java/co/nimblehq/template/EmptyHiltActivity.kt diff --git a/CoroutineTemplate/app/src/main/AndroidManifest.xml b/template/app/src/main/AndroidManifest.xml similarity index 100% rename from CoroutineTemplate/app/src/main/AndroidManifest.xml rename to template/app/src/main/AndroidManifest.xml diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/TemplateApplication.kt b/template/app/src/main/java/co/nimblehq/template/TemplateApplication.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/TemplateApplication.kt rename to template/app/src/main/java/co/nimblehq/template/TemplateApplication.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/AppModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/MoshiModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/NavigatorModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/OkHttpClientModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/RepositoryModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/RetrofitModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/StorageModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt b/template/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt rename to template/app/src/main/java/co/nimblehq/template/di/modules/main/MainActivityModule.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt b/template/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt rename to template/app/src/main/java/co/nimblehq/template/extension/ViewModelExt.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt b/template/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt rename to template/app/src/main/java/co/nimblehq/template/lib/TypeAlias.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/model/UiModel.kt b/template/app/src/main/java/co/nimblehq/template/model/UiModel.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/model/UiModel.kt rename to template/app/src/main/java/co/nimblehq/template/model/UiModel.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt b/template/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt rename to template/app/src/main/java/co/nimblehq/template/ui/ErrorMapping.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseActivity.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragment.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseComposeFragmentCallbacks.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseFragment.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseFragmentCallbacks.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseNavigator.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/BaseViewModel.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/NavigationEvent.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt b/template/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt rename to template/app/src/main/java/co/nimblehq/template/ui/base/NavigationException.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt b/template/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt rename to template/app/src/main/java/co/nimblehq/template/ui/common/Toaster.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/MainActivity.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/MainNavigator.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/MainViewModel.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeFragment.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/HomeComposeViewModel.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/composables/HomeScreen.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Color.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Dimension.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/compose/theme/Theme.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeFragment.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt b/template/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt rename to template/app/src/main/java/co/nimblehq/template/ui/screens/xml/HomeViewModel.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt b/template/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt rename to template/app/src/main/java/co/nimblehq/template/util/DispatchersProvider.kt diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt b/template/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt similarity index 100% rename from CoroutineTemplate/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt rename to template/app/src/main/java/co/nimblehq/template/util/DispatchersProviderImpl.kt diff --git a/CoroutineTemplate/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/CoroutineTemplate/app/src/main/res/drawable/ic_launcher_background.xml b/template/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/drawable/ic_launcher_background.xml rename to template/app/src/main/res/drawable/ic_launcher_background.xml diff --git a/CoroutineTemplate/app/src/main/res/layout/activity_main.xml b/template/app/src/main/res/layout/activity_main.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/layout/activity_main.xml rename to template/app/src/main/res/layout/activity_main.xml diff --git a/CoroutineTemplate/app/src/main/res/layout/fragment_home.xml b/template/app/src/main/res/layout/fragment_home.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/layout/fragment_home.xml rename to template/app/src/main/res/layout/fragment_home.xml diff --git a/CoroutineTemplate/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/CoroutineTemplate/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/CoroutineTemplate/app/src/main/res/mipmap-hdpi/ic_launcher.png b/template/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to template/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/template/app/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to template/app/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-mdpi/ic_launcher.png b/template/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to template/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/template/app/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to template/app/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/template/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to template/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/template/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to template/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/CoroutineTemplate/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from CoroutineTemplate/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml b/template/app/src/main/res/navigation/nav_graph_main.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/navigation/nav_graph_main.xml rename to template/app/src/main/res/navigation/nav_graph_main.xml diff --git a/CoroutineTemplate/app/src/main/res/values/colors.xml b/template/app/src/main/res/values/colors.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/values/colors.xml rename to template/app/src/main/res/values/colors.xml diff --git a/CoroutineTemplate/app/src/main/res/values/dimens.xml b/template/app/src/main/res/values/dimens.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/values/dimens.xml rename to template/app/src/main/res/values/dimens.xml diff --git a/CoroutineTemplate/app/src/main/res/values/strings.xml b/template/app/src/main/res/values/strings.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/values/strings.xml rename to template/app/src/main/res/values/strings.xml diff --git a/CoroutineTemplate/app/src/main/res/values/styles.xml b/template/app/src/main/res/values/styles.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/values/styles.xml rename to template/app/src/main/res/values/styles.xml diff --git a/CoroutineTemplate/app/src/main/res/xml/network_security_config.xml b/template/app/src/main/res/xml/network_security_config.xml similarity index 100% rename from CoroutineTemplate/app/src/main/res/xml/network_security_config.xml rename to template/app/src/main/res/xml/network_security_config.xml diff --git a/CoroutineTemplate/app/src/staging/res/values/strings.xml b/template/app/src/staging/res/values/strings.xml similarity index 100% rename from CoroutineTemplate/app/src/staging/res/values/strings.xml rename to template/app/src/staging/res/values/strings.xml diff --git a/CoroutineTemplate/app/src/staging/res/xml/network_security_config.xml b/template/app/src/staging/res/xml/network_security_config.xml similarity index 100% rename from CoroutineTemplate/app/src/staging/res/xml/network_security_config.xml rename to template/app/src/staging/res/xml/network_security_config.xml diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/TestModules.kt b/template/app/src/test/java/co/nimblehq/template/test/TestModules.kt similarity index 100% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/TestModules.kt rename to template/app/src/test/java/co/nimblehq/template/test/TestModules.kt diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt b/template/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt similarity index 100% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt rename to template/app/src/test/java/co/nimblehq/template/test/ViewModelExt.kt diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt b/template/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt similarity index 100% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt rename to template/app/src/test/java/co/nimblehq/template/ui/BaseFragmentTest.kt diff --git a/CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt b/template/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt similarity index 100% rename from CoroutineTemplate/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt rename to template/app/src/test/java/co/nimblehq/template/ui/screens/xml/HomeFragmentTest.kt diff --git a/CoroutineTemplate/app/src/test/resources/robolectric.properties b/template/app/src/test/resources/robolectric.properties similarity index 100% rename from CoroutineTemplate/app/src/test/resources/robolectric.properties rename to template/app/src/test/resources/robolectric.properties diff --git a/CoroutineTemplate/build.gradle.kts b/template/build.gradle.kts similarity index 100% rename from CoroutineTemplate/build.gradle.kts rename to template/build.gradle.kts diff --git a/CoroutineTemplate/buildSrc/build.gradle.kts b/template/buildSrc/build.gradle.kts similarity index 100% rename from CoroutineTemplate/buildSrc/build.gradle.kts rename to template/buildSrc/build.gradle.kts diff --git a/CoroutineTemplate/buildSrc/src/main/java/Configurations.kt b/template/buildSrc/src/main/java/Configurations.kt similarity index 100% rename from CoroutineTemplate/buildSrc/src/main/java/Configurations.kt rename to template/buildSrc/src/main/java/Configurations.kt diff --git a/CoroutineTemplate/buildSrc/src/main/java/FileExt.kt b/template/buildSrc/src/main/java/FileExt.kt similarity index 100% rename from CoroutineTemplate/buildSrc/src/main/java/FileExt.kt rename to template/buildSrc/src/main/java/FileExt.kt diff --git a/CoroutineTemplate/buildSrc/src/main/java/Versions.kt b/template/buildSrc/src/main/java/Versions.kt similarity index 100% rename from CoroutineTemplate/buildSrc/src/main/java/Versions.kt rename to template/buildSrc/src/main/java/Versions.kt diff --git a/CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts b/template/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts similarity index 100% rename from CoroutineTemplate/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts rename to template/buildSrc/src/main/java/plugins/jacoco-report.gradle.kts diff --git a/CoroutineTemplate/config/debug.keystore b/template/config/debug.keystore similarity index 100% rename from CoroutineTemplate/config/debug.keystore rename to template/config/debug.keystore diff --git a/CoroutineTemplate/data/.gitignore b/template/data/.gitignore similarity index 100% rename from CoroutineTemplate/data/.gitignore rename to template/data/.gitignore diff --git a/CoroutineTemplate/data/build.gradle.kts b/template/data/build.gradle.kts similarity index 100% rename from CoroutineTemplate/data/build.gradle.kts rename to template/data/build.gradle.kts diff --git a/CoroutineTemplate/data/proguard-rules.pro b/template/data/proguard-rules.pro similarity index 100% rename from CoroutineTemplate/data/proguard-rules.pro rename to template/data/proguard-rules.pro diff --git a/CoroutineTemplate/data/src/main/AndroidManifest.xml b/template/data/src/main/AndroidManifest.xml similarity index 100% rename from CoroutineTemplate/data/src/main/AndroidManifest.xml rename to template/data/src/main/AndroidManifest.xml diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt b/template/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt rename to template/data/src/main/java/co/nimblehq/template/data/repository/RepositoryImpl.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/response/Response.kt b/template/data/src/main/java/co/nimblehq/template/data/response/Response.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/response/Response.kt rename to template/data/src/main/java/co/nimblehq/template/data/response/Response.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt b/template/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt rename to template/data/src/main/java/co/nimblehq/template/data/service/ApiService.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt b/template/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt rename to template/data/src/main/java/co/nimblehq/template/data/service/providers/ApiServiceProvider.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt b/template/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt rename to template/data/src/main/java/co/nimblehq/template/data/service/providers/ConverterFactoryProvider.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt b/template/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt rename to template/data/src/main/java/co/nimblehq/template/data/service/providers/MoshiBuilderProvider.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt b/template/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt rename to template/data/src/main/java/co/nimblehq/template/data/service/providers/RetrofitProvider.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt b/template/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt rename to template/data/src/main/java/co/nimblehq/template/data/storage/BaseSharedPreferences.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt b/template/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt rename to template/data/src/main/java/co/nimblehq/template/data/storage/EncryptedSharedPreferences.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt b/template/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt rename to template/data/src/main/java/co/nimblehq/template/data/storage/NormalSharedPreferences.kt diff --git a/CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt b/template/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt similarity index 100% rename from CoroutineTemplate/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt rename to template/data/src/main/java/co/nimblehq/template/data/storage/SharedPreferencesExt.kt diff --git a/CoroutineTemplate/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt b/template/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt similarity index 100% rename from CoroutineTemplate/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt rename to template/data/src/test/java/co/nimblehq/template/data/repository/RepositoryTest.kt diff --git a/CoroutineTemplate/detekt-config.yml b/template/detekt-config.yml similarity index 100% rename from CoroutineTemplate/detekt-config.yml rename to template/detekt-config.yml diff --git a/CoroutineTemplate/domain/.gitignore b/template/domain/.gitignore similarity index 100% rename from CoroutineTemplate/domain/.gitignore rename to template/domain/.gitignore diff --git a/CoroutineTemplate/domain/build.gradle.kts b/template/domain/build.gradle.kts similarity index 100% rename from CoroutineTemplate/domain/build.gradle.kts rename to template/domain/build.gradle.kts diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt b/template/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt similarity index 100% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt rename to template/domain/src/main/java/co/nimblehq/template/domain/model/Model.kt diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt b/template/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt similarity index 100% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt rename to template/domain/src/main/java/co/nimblehq/template/domain/repository/Repository.kt diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt b/template/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt similarity index 100% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt rename to template/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCase.kt diff --git a/CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt b/template/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt similarity index 100% rename from CoroutineTemplate/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt rename to template/domain/src/main/java/co/nimblehq/template/domain/usecase/UseCaseResult.kt diff --git a/CoroutineTemplate/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt b/template/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt similarity index 100% rename from CoroutineTemplate/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt rename to template/domain/src/test/java/co/nimblehq/template/domain/usecase/UseCaseTest.kt diff --git a/CoroutineTemplate/gradle.properties b/template/gradle.properties similarity index 100% rename from CoroutineTemplate/gradle.properties rename to template/gradle.properties diff --git a/CoroutineTemplate/gradle/wrapper/gradle-wrapper.jar b/template/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from CoroutineTemplate/gradle/wrapper/gradle-wrapper.jar rename to template/gradle/wrapper/gradle-wrapper.jar diff --git a/CoroutineTemplate/gradle/wrapper/gradle-wrapper.properties b/template/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from CoroutineTemplate/gradle/wrapper/gradle-wrapper.properties rename to template/gradle/wrapper/gradle-wrapper.properties diff --git a/CoroutineTemplate/gradlew b/template/gradlew similarity index 100% rename from CoroutineTemplate/gradlew rename to template/gradlew diff --git a/CoroutineTemplate/gradlew.bat b/template/gradlew.bat similarity index 100% rename from CoroutineTemplate/gradlew.bat rename to template/gradlew.bat diff --git a/CoroutineTemplate/settings.gradle.kts b/template/settings.gradle.kts similarity index 100% rename from CoroutineTemplate/settings.gradle.kts rename to template/settings.gradle.kts diff --git a/CoroutineTemplate/signing.properties b/template/signing.properties similarity index 100% rename from CoroutineTemplate/signing.properties rename to template/signing.properties From 15fa3b1aa98f0e0cae790df7271aab0af90f34b4 Mon Sep 17 00:00:00 2001 From: "Tobias (Toby) Heuts" Date: Mon, 25 Jul 2022 11:01:15 +0700 Subject: [PATCH 9/9] [#244] Apply code review changes --- Dangerfile | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dangerfile b/Dangerfile index 3e44eae40..a9a3f1954 100644 --- a/Dangerfile +++ b/Dangerfile @@ -29,9 +29,9 @@ Dir[lint_dir].each do |file_name| android_lint.lint(inline_mode: true) end -# Show Danger test coverage report from Jacoco for Template +# Show Danger test coverage report from Jacoco for template jacoco_dir = "template/**/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml" -markdown "## Template Jacoco report:" +markdown "## template Jacoco report:" Dir[jacoco_dir].each do |file_name| # Report coverage of modified files, warn if total project coverage is under 80% # or if any modified file's coverage is under 95% diff --git a/README.md b/README.md index 45c59cc26..243bff8db 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ --- -Our Android template: **[Template](https://github.com/nimblehq/android-templates/tree/develop/template)** +Our Android template: **[template](https://github.com/nimblehq/android-templates/tree/develop/template)** ## Setup