Created
June 4, 2024 20:47
-
-
Save MkhytarMkhoian/db2f0e56c4bdde9eb78c0042b5bd7b84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AppDeepLinkLocalDataSource( | |
private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO, | |
) { | |
companion object { | |
private const val RYDER_ID = "ryderId" | |
private const val PRICE = "price" | |
const val HOME = "moove://app/home" | |
const val FARE_LIST = "moove://app/fare_list" | |
const val CONFIRM_CONFIRMATION = "/ticket/confirmation" | |
const val MOOVE_CONFIRM_CONFIRMATION = "moove://app/confirmation" | |
} | |
suspend fun getDeepLinkData(uri: String): DeepLink = withContext(backgroundDispatcher) { | |
when { | |
uri.matchesPattern(CONFIRM_CONFIRMATION) -> { | |
val innerUri = URI.create(uri) | |
val params = getQueryParams(innerUri) | |
AppDeepLink.Confirmation( | |
ryderId = params[RYDER_ID]!!, | |
fare = Fare( | |
description = "", | |
price = params[PRICE]?.toFloat()!! | |
), | |
) | |
} | |
uri.matchesPattern(MOOVE_CONFIRM_CONFIRMATION) -> { | |
val innerUri = URI.create(uri) | |
val params = getQueryParams(innerUri) | |
AppDeepLink.Confirmation( | |
ryderId = params[RYDER_ID]!!, | |
fare = Fare( | |
description = "", | |
price = params[PRICE]?.toFloat()!! | |
), | |
) | |
} | |
uri.isThat(FARE_LIST) -> { | |
val innerUri = URI.create(uri) | |
val params = getQueryParams(innerUri) | |
AppDeepLink.FareList(ryderId = params[RYDER_ID]!!) | |
} | |
uri.isThat(HOME) || uri.matchesPattern(HOME) -> AppDeepLink.Home | |
else -> AppDeepLink.Unknown | |
} | |
} | |
private fun String.isThat(type: String): Boolean { | |
/** | |
* Handle two cases with slash symbol at the end and without it | |
* app/home/ and app/home | |
*/ | |
return contains(type, ignoreCase = true) | |
} | |
private fun getQueryParams(url: URI): Map<String, String> { | |
val query = url.query ?: return emptyMap() | |
return query | |
.split("&".toRegex()) | |
.filter { it.isNotEmpty() } | |
.map(::mapQueryParameter) | |
.associateBy(keySelector = { it.first }, valueTransform = { it.second }) | |
} | |
private fun mapQueryParameter(query: String): Pair<String, String> { | |
val index = query.indexOf("=") | |
val key = if (index > 0) query.substring(0, index) else query | |
val value = if (index > 0 && query.length > index + 1) { | |
query.substring(index + 1) | |
} else null | |
return Pair( | |
URLDecoder.decode(key, StandardCharsets.UTF_8.name()), | |
URLDecoder.decode(value, StandardCharsets.UTF_8.name()) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment