Skip to content

Commit

Permalink
ADD manual and auto formatting to all files in the project
Browse files Browse the repository at this point in the history
  • Loading branch information
sebaslogen committed Jan 12, 2024
1 parent c17dff4 commit 0560335
Show file tree
Hide file tree
Showing 45 changed files with 336 additions and 294 deletions.
8 changes: 4 additions & 4 deletions app/src/main/kotlin/nl/q42/template/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ import nl.q42.template.ui.theme.AppTheme

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {

AppTheme {

val navController = rememberNavController()

Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
AppNavigation(navController = navController, navGraph = NavGraphs.root)
}
}
Expand Down
1 change: 0 additions & 1 deletion app/src/main/kotlin/nl/q42/template/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import io.github.aakira.napier.Napier

@HiltAndroidApp
class MainApplication : Application() {

override fun onCreate() {
super.onCreate()

Expand Down
5 changes: 2 additions & 3 deletions app/src/main/kotlin/nl/q42/template/di/ConfigModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import nl.q42.template.BuildConfig
import nl.q42.template.core.network.di.ConfigApiMainPath
import nl.q42.template.core.network.di.ConfigLogHttpCalls
import javax.inject.Singleton

/**
* All application wide config can go in here. Used so that other modules don't need to access the BuildConfig, which has drawbacks and can cause bugs:
Expand All @@ -16,7 +16,6 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class ConfigModule {

@Provides
@Singleton
@ConfigApiMainPath
Expand All @@ -26,4 +25,4 @@ class ConfigModule {
@Singleton
@ConfigLogHttpCalls
fun configIsLoggingHttpCalls(): Boolean = BuildConfig.config_log_http_calls
}
}
72 changes: 39 additions & 33 deletions app/src/main/kotlin/nl/q42/template/navigation/NavGraphs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,42 @@ import nl.q42.template.ui.onboarding.start.destinations.OnboardingStartScreenDes
* More info: https://composedestinations.rafaelcosta.xyz/codegenconfigs/#multi-module-configs
*/
object NavGraphs {

val home = object : NavGraphSpec {
override val route = AppGraphRoutes.home

override val startRoute = HomeScreenDestination

override val destinationsByRoute = listOf<DestinationSpec<*>>(
HomeScreenDestination,
HomeSecondScreenDestination,
)
.associateBy { it.route }
}

val onboarding = object : NavGraphSpec {
override val route = AppGraphRoutes.onboarding

override val startRoute = OnboardingStartScreenDestination

override val destinationsByRoute = listOf<DestinationSpec<*>>(
OnboardingStartScreenDestination,
)
.associateBy { it.route }
}

val root = object : NavGraphSpec {
override val route = AppGraphRoutes.root
override val startRoute = home
override val destinationsByRoute = emptyMap<String, DestinationSpec<*>>()
override val nestedNavGraphs = listOf(
home, onboarding
)
}
}
val home =
object : NavGraphSpec {
override val route = AppGraphRoutes.HOME

override val startRoute = HomeScreenDestination

override val destinationsByRoute =
listOf<DestinationSpec<*>>(
HomeScreenDestination,
HomeSecondScreenDestination
)
.associateBy { it.route }
}

val onboarding =
object : NavGraphSpec {
override val route = AppGraphRoutes.ONBOARDING

override val startRoute = OnboardingStartScreenDestination

override val destinationsByRoute =
listOf<DestinationSpec<*>>(
OnboardingStartScreenDestination
)
.associateBy { it.route }
}

val root =
object : NavGraphSpec {
override val route = AppGraphRoutes.ROOT
override val startRoute = home
override val destinationsByRoute = emptyMap<String, DestinationSpec<*>>()
override val nestedNavGraphs =
listOf(
home,
onboarding
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ import nl.q42.template.actionresult.domain.ActionResult
/**
* Shortcut to react on success and error states of an action. Because this looks sexier in the code.
*/
suspend fun <T> handleAction(
action: ActionResult<T>,
onSuccess: suspend (T) -> Unit,
onError: suspend (ActionResult.Error) -> Unit,
) {
suspend fun <T> handleAction(action: ActionResult<T>, onSuccess: suspend (T) -> Unit, onError: suspend (ActionResult.Error) -> Unit) {
when (action) {
is ActionResult.Success -> onSuccess(action.result)
is ActionResult.Error -> onError(action)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,82 +3,98 @@ package nl.q42.template.actionresult.data
import com.haroldadmin.cnradapter.NetworkResponse
import com.squareup.moshi.JsonEncodingException
import io.github.aakira.napier.Napier
import kotlinx.coroutines.CancellationException
import nl.q42.template.actionresult.domain.ActionResult
import java.io.EOFException
import java.io.IOException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import kotlinx.coroutines.CancellationException
import nl.q42.template.actionresult.domain.ActionResult

private const val UNAUTHENTICATED_STATUSES = 401
private const val NOT_FOUND_REQUESTS_STATUS = 404
private const val TOO_MANY_REQUESTS_STATUS = 429

private fun isUnAuthorized(httpStatusCode: Int?) = httpStatusCode == UNAUTHENTICATED_STATUSES

private fun isNotFound(httpStatusCode: Int?) = httpStatusCode == NOT_FOUND_REQUESTS_STATUS

private fun isTooManyRequests(httpStatusCode: Int?) = httpStatusCode == TOO_MANY_REQUESTS_STATUS

/**
* Maps a remote [NetworkResponse] to an [ActionResult] transforming all possible errors and exceptions into our domain error models
*/
suspend fun <T : Any> mapToActionResult(request: suspend () -> NetworkResponse<T, ApiErrorResponse>): ActionResult<T> =
try {
request().networkResponseToActionResult()
} catch (e: Exception) {
if (e is CancellationException) ActionResult.Error.Cancelled(e) else ActionResult.Error.Other(e)
suspend fun <T : Any> mapToActionResult(request: suspend () -> NetworkResponse<T, ApiErrorResponse>): ActionResult<T> = try {
request().networkResponseToActionResult()
} catch (e: Exception) {
if (e is CancellationException) {
ActionResult.Error.Cancelled(
e
)
} else {
ActionResult.Error.Other(e)
}
}

private fun <T : Any> NetworkResponse<T, ApiErrorResponse>.networkResponseToActionResult(): ActionResult<T> =
when (this) {
is NetworkResponse.Success -> ActionResult.Success(this.body)
is NetworkResponse.ServerError -> {
val errorMessage: String? = this.body?.message
val exception = Exception("$errorMessage $this.code")
when {
isNotFound(this.code) -> ActionResult.Error.NotFoundError
isTooManyRequests(this.code) -> ActionResult.Error.TooManyRequests(exception)
isUnAuthorized(this.code) -> ActionResult.Error.UnAuthorized(exception, errorMessage)
// a 404 is not a ServerError, but an UnknownError (mapping to Error.NotFoundError)
!errorMessage.isNullOrBlank() -> ActionResult.Error.ServerError(exception, errorMessage)
errorMessage == null -> ActionResult.Error.InvalidErrorResponse(exception, this.code)
else -> ActionResult.Error.Other(exception)
}
private fun <T : Any> NetworkResponse<T, ApiErrorResponse>.networkResponseToActionResult(): ActionResult<T> = when (this) {
is NetworkResponse.Success -> ActionResult.Success(this.body)
is NetworkResponse.ServerError -> {
val errorMessage: String? = this.body?.message
val exception = Exception("$errorMessage $this.code")
when {
isNotFound(this.code) -> ActionResult.Error.NotFoundError
isTooManyRequests(this.code) -> ActionResult.Error.TooManyRequests(exception)
isUnAuthorized(
this.code
) -> ActionResult.Error.UnAuthorized(exception, errorMessage)
// a 404 is not a ServerError, but an UnknownError (mapping to Error.NotFoundError)
!errorMessage.isNullOrBlank() -> ActionResult.Error.ServerError(
exception,
errorMessage
)
errorMessage == null -> ActionResult.Error.InvalidErrorResponse(
exception,
this.code
)
else -> ActionResult.Error.Other(exception)
}
}

is NetworkResponse.NetworkError -> // Used to represent connectivity errors
when (this.error) {
is UnknownHostException, is ConnectException, is SocketTimeoutException -> {
ActionResult.Error.NetworkError(this.error)
}

is JsonEncodingException, is EOFException -> {
// let's log this error, includes a corrupt/broken json response:
ActionResult.Error.Other(this.error)
}
is NetworkResponse.NetworkError -> // Used to represent connectivity errors
when (this.error) {
is UnknownHostException, is ConnectException, is SocketTimeoutException -> {
ActionResult.Error.NetworkError(this.error)
}

else -> ActionResult.Error.Other(this.error)
is JsonEncodingException, is EOFException -> {
// let's log this error, includes a corrupt/broken json response:
ActionResult.Error.Other(this.error)
}

is NetworkResponse.UnknownError -> {
val statusCode = this.code
val errorMessage = "Received NetworkResponse.UnknownError with response code $statusCode and header ${this.headers}"
val exception = IOException(errorMessage, this.error)
Napier.w(this.error) { "NetworkResponse.UnknownError" }
when {
statusCode == null -> {
ActionResult.Error.InvalidErrorResponse(exception)
}
else -> ActionResult.Error.Other(this.error)
}

isTooManyRequests(statusCode) -> {
ActionResult.Error.TooManyRequests(exception)
}
is NetworkResponse.UnknownError -> {
val statusCode = this.code
val errorMessage = "Received NetworkResponse.UnknownError with response code $statusCode and header ${this.headers}"
val exception = IOException(errorMessage, this.error)
Napier.w(this.error) { "NetworkResponse.UnknownError" }
when {
statusCode == null -> {
ActionResult.Error.InvalidErrorResponse(exception)
}

isTooManyRequests(statusCode) -> {
ActionResult.Error.TooManyRequests(exception)
}

isNotFound(statusCode) -> ActionResult.Error.NotFoundError
isUnAuthorized(statusCode) -> ActionResult.Error.UnAuthorized(exception, errorMessage)
else -> {
ActionResult.Error.InvalidErrorResponse(exception, statusCode)
}
isNotFound(statusCode) -> ActionResult.Error.NotFoundError
isUnAuthorized(
statusCode
) -> ActionResult.Error.UnAuthorized(exception, errorMessage)
else -> {
ActionResult.Error.InvalidErrorResponse(exception, statusCode)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ import com.squareup.moshi.JsonClass
* More info: https://haroldadmin.github.io/NetworkResponseAdapter/
*/
@JsonClass(generateAdapter = true)
data class ApiErrorResponse(val message: String)
data class ApiErrorResponse(val message: String)
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package nl.q42.template.actionresult.domain

sealed class ActionResult<out T : Any?> {

/**
* An error class used so that feature modules can give an exact error message to the user.
*/
sealed class Error(open val exception: Exception) : ActionResult<Nothing>() {

data class UnAuthorized(override val exception: Exception, val message: String?) : Error(exception)
data class UnAuthorized(
override val exception: Exception,
val message: String?
) : Error(exception)

data class TooManyRequests(override val exception: Exception) : Error(exception)

Expand All @@ -19,7 +20,9 @@ sealed class ActionResult<out T : Any?> {
) :
Error(exception)

data class ServerError(override val exception: Exception, val message: String) : Error(exception)
data class ServerError(override val exception: Exception, val message: String) : Error(
exception
)

data object NotFoundError : Error(Exception("404: Not Found"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,3 @@ fun <S, T> ActionResult<List<S>>.mapList(mapper: (S) -> T): ActionResult<List<T>
is ActionResult.Error -> this
is ActionResult.Success -> ActionResult.Success(this.result.map { mapper(it) })
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package nl.q42.template.navigation
* App graph routes are here so all features can navigate to the root of another feature.
*/
object AppGraphRoutes {
const val root = "root"
const val home = "home"
const val onboarding = "onboarding"
}
const val ROOT = "root"
const val HOME = "home"
const val ONBOARDING = "onboarding"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,20 @@ import nl.q42.template.navigation.transitions.defaultPopExitTransition
@OptIn(ExperimentalMaterialNavigationApi::class)
@ExperimentalAnimationApi
@Composable
fun AppNavigation(
navController: NavHostController,
navGraph: NavGraphSpec,
modifier: Modifier = Modifier,
) {
fun AppNavigation(navController: NavHostController, navGraph: NavGraphSpec, modifier: Modifier = Modifier) {
DestinationsNavHost(
engine = rememberAnimatedNavHostEngine(
rootDefaultAnimations = RootNavGraphDefaultAnimations(
engine =
rememberAnimatedNavHostEngine(
rootDefaultAnimations =
RootNavGraphDefaultAnimations(
enterTransition = { defaultEnterTransition(initialState, targetState) },
exitTransition = { defaultExitTransition(initialState, targetState) },
popEnterTransition = { defaultPopEnterTransition() },
popExitTransition = { defaultPopExitTransition() },
popExitTransition = { defaultPopExitTransition() }
)
),
navController = navController,
navGraph = navGraph,
modifier = modifier,
modifier = modifier
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import nl.q42.template.navigation.viewmodel.RouteNavigator
@Module
@InstallIn(ViewModelComponent::class)
class NavigationModule {

@Provides
@ViewModelScoped
fun bindRouteNavigator(): RouteNavigator = MyRouteNavigator()
}
}
Loading

0 comments on commit 0560335

Please sign in to comment.