working on videoCall notification
parent
529711d2ce
commit
e06bd6a4f8
@ -1,7 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
/**
|
||||
* A functional interface representing an action that gets executed
|
||||
* upon an error by an [ErrorHandler].
|
||||
*/
|
||||
typealias Action = (Throwable, ErrorHandler) -> Unit
|
||||
@ -1,34 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
|
||||
/**
|
||||
* Container to ease passing around a tuple of two objects. This object provides a sensible
|
||||
* implementation of equals(), returning true if equals() is true on each of the contained
|
||||
* objects.
|
||||
*/
|
||||
class ActionEntry
|
||||
/**
|
||||
* Constructor for an ActionEntry.
|
||||
*
|
||||
* @param matcher the matcher object in the ActionEntry
|
||||
* @param action the action object in the ActionEntry
|
||||
*/(
|
||||
val matcher: Matcher,
|
||||
val action: Action
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
val that = other as ActionEntry
|
||||
return if (matcher != that.matcher) false else action == that.action
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a hash code using the hash codes of the underlying objects
|
||||
*
|
||||
* @return a hashcode of the ActionEntry
|
||||
*/
|
||||
override fun hashCode(): Int {
|
||||
return matcher.hashCode() xor action.hashCode()
|
||||
}
|
||||
}
|
||||
@ -1,505 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
import java.util.HashMap
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* https://github.com/mgray88/kotlin-error-handler
|
||||
* An ErrorHandler is responsible for handling an error by executing one or more actions,
|
||||
* instances of [Action], that are found to match the error.
|
||||
*/
|
||||
|
||||
class ErrorHandler private constructor() {
|
||||
|
||||
private val errorCodeMap = mutableMapOf<ErrorCodeIdentifier<*>, MatcherFactory<*>>()
|
||||
private val actions = mutableListOf<ActionEntry>()
|
||||
private val otherwiseActions= mutableListOf<Action>()
|
||||
private val alwaysActions = mutableListOf<Action>()
|
||||
private var localContext: ThreadLocal<Context> = object : ThreadLocal<Context>() {
|
||||
override fun initialValue(): Context {
|
||||
return Context()
|
||||
}
|
||||
}
|
||||
private var parentErrorHandler: ErrorHandler? = null
|
||||
|
||||
/**
|
||||
* Create a new ErrorHandler with the given one as parent.
|
||||
*
|
||||
* @param parentErrorHandler the parent @{link ErrorHandler}
|
||||
*/
|
||||
private constructor(parentErrorHandler: ErrorHandler) : this() {
|
||||
this.parentErrorHandler = parentErrorHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Register `action` to be executed by [.handle],
|
||||
* if the thrown error matches the `matcher`.
|
||||
*
|
||||
* @param matcher a matcher to match the thrown error
|
||||
* @param action the associated action
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun on(
|
||||
matcher: Matcher,
|
||||
action: Action
|
||||
): ErrorHandler {
|
||||
actions.add(ActionEntry(matcher, action))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin <1.4 lambda compatibility for `[.on(Matcher, Action)]`
|
||||
*/
|
||||
fun on(
|
||||
matcher: (Throwable) -> Boolean,
|
||||
action: Action
|
||||
): ErrorHandler {
|
||||
return on(object : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return matcher(throwable)
|
||||
}
|
||||
}, action)
|
||||
}
|
||||
|
||||
/**
|
||||
* Register `action` to be executed by [.handle],
|
||||
* if the thrown error is an instance of `exceptionClass`.
|
||||
*
|
||||
* @param exceptionClass the class of the error
|
||||
* @param action the associated action
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun on(
|
||||
exceptionClass: KClass<out Throwable>,
|
||||
action: Action
|
||||
): ErrorHandler {
|
||||
actions.add(ActionEntry(ExceptionMatcher(exceptionClass), action))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Register `action` to be executed by [.handle],
|
||||
* if the thrown error is bound (associated) to `errorCode`.
|
||||
*
|
||||
*
|
||||
* See [.bindClass] and [.bind]
|
||||
* on how to associate arbitrary error codes with actual Throwables via [Matcher].
|
||||
*
|
||||
* @param <T> the error code type
|
||||
* @param errorCode the error code
|
||||
* @param action the associated action
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
</T> */
|
||||
fun <T : Any> on(
|
||||
errorCode: T,
|
||||
action: Action
|
||||
): ErrorHandler {
|
||||
val matcherFactory: MatcherFactory<T> =
|
||||
getMatcherFactoryForErrorCode(errorCode)
|
||||
?: throw UnknownErrorCodeException(errorCode)
|
||||
actions.add(ActionEntry(matcherFactory.build(errorCode), action))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Register `action` to be executed in case no other *conditional*
|
||||
* action gets executed.
|
||||
*
|
||||
* @param action the action
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun otherwise(action: Action): ErrorHandler {
|
||||
otherwiseActions.add(action)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Register `action` to be executed on all errors.
|
||||
*
|
||||
* @param action the action
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun always(action: Action): ErrorHandler {
|
||||
alwaysActions.add(action)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip all following actions registered via an `on` method
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun skipFollowing(): ErrorHandler {
|
||||
localContext.get().skipFollowing = true
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip all actions registered via [.always]
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun skipAlways(): ErrorHandler {
|
||||
localContext.get().skipAlways = true
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the default matching actions if any
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun skipDefaults(): ErrorHandler {
|
||||
localContext.get().skipDefaults = true
|
||||
return this
|
||||
}
|
||||
|
||||
private fun handle(
|
||||
error: Throwable,
|
||||
context: ThreadLocal<Context>
|
||||
) {
|
||||
localContext = context
|
||||
val ctx = localContext.get()
|
||||
for (actionEntry in actions) {
|
||||
if (ctx.skipFollowing) break
|
||||
if (actionEntry.matcher.matches(error)) {
|
||||
actionEntry.action(error, this)
|
||||
ctx.handled = true
|
||||
}
|
||||
}
|
||||
if (!ctx.handled && otherwiseActions.isNotEmpty()) {
|
||||
for (action in otherwiseActions) {
|
||||
action(error, this)
|
||||
ctx.handled = true
|
||||
}
|
||||
}
|
||||
if (!ctx.skipAlways) {
|
||||
for (action in alwaysActions) {
|
||||
action(error, this)
|
||||
ctx.handled = true
|
||||
}
|
||||
}
|
||||
if (!ctx.skipDefaults) {
|
||||
parentErrorHandler?.handle(error, localContext)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a custom code block and assign current ErrorHandler instance
|
||||
* to handle a possible exception throw in 'catch'.
|
||||
*
|
||||
* @param closure functional interface containing Exception prone code
|
||||
*/
|
||||
fun runHandling(closure: () -> Unit) {
|
||||
try {
|
||||
closure()
|
||||
} catch (throwable: Throwable) {
|
||||
handle(throwable, localContext)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle `error` by executing all matching actions.
|
||||
*
|
||||
* @param error the error as a [Throwable]
|
||||
*/
|
||||
fun handle(error: Throwable) {
|
||||
this.handle(error, localContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind an `errorCode` to a `Matcher`, using a `MatcherFactory`.
|
||||
*
|
||||
*
|
||||
*
|
||||
* For example, when we need to catch a network timeout it's better to just write "timeout"
|
||||
* instead of a train-wreck expression. So we need to bind this "timeout" error code to an actual
|
||||
* condition that will check the actual error when it occurs to see if its a network timeout or not.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* ```
|
||||
* ErrorHandler
|
||||
* .defaultErrorHandler()
|
||||
* .bind("timeout") { errorCode ->
|
||||
* Matcher { throwable ->
|
||||
* return (throwable is SocketTimeoutException) && throwable.message.contains("Read timed out")
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* ErrorHandler
|
||||
* .create()
|
||||
* .on("timeout") { throwable, handler ->
|
||||
* showOfflineScreen()
|
||||
* }
|
||||
* ```
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param <T> the error code type
|
||||
* @param errorCode the errorCode value, can use a primitive for clarity and let it be autoboxed
|
||||
* @param matcherFactory a factory that given an error code, provides a matcher to match the error against it
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun <T : Any> bind(
|
||||
errorCode: T,
|
||||
matcherFactory: MatcherFactory<T>
|
||||
): ErrorHandler {
|
||||
errorCodeMap[ErrorCodeIdentifier(errorCode)] = matcherFactory
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin <1.4 lambda compatibility for `[.bind(T, MatcherFactory<T>)]`
|
||||
*/
|
||||
fun <T : Any> bind(
|
||||
errorCode: T,
|
||||
matcherFactory: (T) -> (Throwable) -> Boolean
|
||||
): ErrorHandler {
|
||||
return bind(errorCode, object : MatcherFactory<T> {
|
||||
override fun build(errorCode: T): Matcher {
|
||||
val matcher = matcherFactory(errorCode)
|
||||
return object : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return matcher(throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind an `errorCode` `Class` to a `Matcher`, using a `MatcherFactory`.
|
||||
*
|
||||
*
|
||||
*
|
||||
* For example, when we prefer using plain integers to refer to HTTP errors instead of
|
||||
* checking the HTTPException status code every time.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* ```
|
||||
* ErrorHandler
|
||||
* .defaultErrorHandler()
|
||||
* .bindClass(Integer::class) { errorCode ->
|
||||
* Matcher { throwable ->
|
||||
* return throwable is HttpException && throwable.code() == errorCode
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* ErrorHandler
|
||||
* .create()
|
||||
* .on(404) { throwable, handler ->
|
||||
* showResourceNotFoundError()
|
||||
* }
|
||||
* .on(500) { throwable, handler ->
|
||||
* showServerError()
|
||||
* }
|
||||
* ````
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> the error code type
|
||||
* @param errorCodeClass the errorCode class
|
||||
* @param matcherFactory a factory that given an error code, provides a matcher to match the error against it
|
||||
* @return the current `ErrorHandler` instance - to use in command chains
|
||||
*/
|
||||
fun <T : Any> bindClass(
|
||||
errorCodeClass: KClass<T>,
|
||||
matcherFactory: MatcherFactory<T>
|
||||
): ErrorHandler {
|
||||
errorCodeMap[ErrorCodeIdentifier(errorCodeClass)] = matcherFactory
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin <1.4 lambda compatibility for `[.bindClass(KClass<T>, MatcherFactory<T>)]`
|
||||
*/
|
||||
fun <T : Any> bindClass(
|
||||
errorCodeClass: KClass<T>,
|
||||
matcherFactory: (T) -> (Throwable) -> Boolean
|
||||
): ErrorHandler {
|
||||
return bindClass(errorCodeClass, object : MatcherFactory<T> {
|
||||
override fun build(errorCode: T): Matcher {
|
||||
val matcher = matcherFactory(errorCode)
|
||||
return object : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return matcher(throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
protected fun <T : Any> getMatcherFactoryForErrorCode(errorCode: T): MatcherFactory<T>? {
|
||||
var matcherFactory: MatcherFactory<T>?
|
||||
matcherFactory = errorCodeMap[ErrorCodeIdentifier(errorCode)] as? MatcherFactory<T>
|
||||
if (matcherFactory != null) {
|
||||
return matcherFactory
|
||||
}
|
||||
|
||||
matcherFactory = errorCodeMap[ErrorCodeIdentifier(errorCode::class)] as? MatcherFactory<T>
|
||||
if (matcherFactory != null) {
|
||||
return matcherFactory
|
||||
}
|
||||
return if (parentErrorHandler != null) {
|
||||
parentErrorHandler?.getMatcherFactoryForErrorCode(errorCode)
|
||||
} else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear ErrorHandler instance from all its registered Actions and Matchers.
|
||||
*/
|
||||
fun clear() {
|
||||
actions.clear()
|
||||
errorCodeMap.clear()
|
||||
otherwiseActions.clear()
|
||||
alwaysActions.clear()
|
||||
localContext.get().clear()
|
||||
}
|
||||
|
||||
private class Context {
|
||||
private val keys = HashMap<String, Any>()
|
||||
var handled = false
|
||||
var skipDefaults = false
|
||||
var skipFollowing = false
|
||||
var skipAlways = false
|
||||
operator fun get(key: Any?): Any? {
|
||||
return keys[key]
|
||||
}
|
||||
|
||||
fun put(key: String, value: Any): Any? {
|
||||
return keys.put(key, value)
|
||||
}
|
||||
|
||||
fun remove(key: Any?): Any? {
|
||||
return keys.remove(key)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
keys.clear()
|
||||
skipDefaults = false
|
||||
skipFollowing = false
|
||||
skipAlways = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to identify an error code either by its "literal" value
|
||||
* or by its Class.
|
||||
*
|
||||
*
|
||||
* When using custom objects as error codes,
|
||||
* make sure you implement [Object.equals] to allow ErrorHandler
|
||||
* perform equality comparisons between instances.
|
||||
*/
|
||||
private class ErrorCodeIdentifier<out T : Any> {
|
||||
private val errorCode: T?
|
||||
private val errorCodeClass: KClass<out T>?
|
||||
|
||||
internal constructor(errorCode: T) {
|
||||
this.errorCode = errorCode
|
||||
this.errorCodeClass = null
|
||||
}
|
||||
|
||||
internal constructor(errorCodeClass: KClass<out T>) {
|
||||
this.errorCode = null
|
||||
this.errorCodeClass = errorCodeClass
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val that = other as ErrorCodeIdentifier<*>
|
||||
|
||||
if (if (errorCode != null) errorCode != that.errorCode else that.errorCode != null) return false
|
||||
return if (errorCodeClass != null) errorCodeClass == that.errorCodeClass else that.errorCodeClass == null
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = errorCode?.hashCode() ?: 0
|
||||
result = 31 * result + (errorCodeClass?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var defaultInstance: ErrorHandler? = null
|
||||
|
||||
/**
|
||||
* Create a new @{link ErrorHandler}, isolated from the default one.
|
||||
*
|
||||
*
|
||||
* In other words, designed to handle all errors by itself without delegating
|
||||
* to the default error handler.
|
||||
*
|
||||
* @return returns a new `ErrorHandler` instance
|
||||
*/
|
||||
@JvmStatic
|
||||
fun createIsolated(): ErrorHandler {
|
||||
return ErrorHandler()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new @{link ErrorHandler}, that delegates to the default one, or the
|
||||
* parent @{link ErrorHandler} passed in
|
||||
*
|
||||
* Any default actions, are always executed after the ones registered on this one.
|
||||
*
|
||||
* @param parentErrorHandler `ErrorHandler` to use as the parent
|
||||
* @return returns a new `ErrorHandler` instance
|
||||
*/
|
||||
@JvmStatic
|
||||
fun create(parentErrorHandler: ErrorHandler? = null): ErrorHandler {
|
||||
return ErrorHandler(parentErrorHandler ?: defaultErrorHandler())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default @{link ErrorHandler}, a singleton object
|
||||
* to which all other instances by default delegate to.
|
||||
*
|
||||
* @return the default @{link ErrorHandler} instance
|
||||
*/
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
fun defaultErrorHandler(): ErrorHandler {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance =
|
||||
ErrorHandler()
|
||||
}
|
||||
return defaultInstance!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around `[.on(KClass, Action)]` to allow action's `Throwable` parameter
|
||||
* to be typed to the `Throwable` expected
|
||||
*/
|
||||
inline fun <reified T : Throwable> ErrorHandler.on(
|
||||
noinline action: (T, ErrorHandler) -> Unit
|
||||
): ErrorHandler {
|
||||
return on(T::class) { throwable, errorHandler ->
|
||||
action(throwable as T, errorHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy `ErrorHandler` initializer which delegates to a parent, or the `defaultErrorHandler`
|
||||
* if the parent is not supplied. Uses optional lambda function to add actions and bindings to
|
||||
* the new `ErrorHandler`
|
||||
*
|
||||
* @param parentErrorHandler (optional) error handler to delegate default actions to
|
||||
* @param apply (optional) apply function for adding actions and binding
|
||||
* @return lazy initialized `ErrorHandler`
|
||||
*/
|
||||
inline fun errorHandler(
|
||||
parentErrorHandler: ErrorHandler? = null,
|
||||
noinline apply: (ErrorHandler.() -> Unit)? = null
|
||||
) = lazy {
|
||||
val eh = ErrorHandler.create(parentErrorHandler)
|
||||
apply?.invoke(eh)
|
||||
return@lazy eh
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class ExceptionMatcher(private val errorClass: KClass<out Throwable>) : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return errorClass.isInstance(throwable)
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
interface Matcher {
|
||||
fun matches(throwable: Throwable): Boolean
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
interface MatcherFactory<in T : Any> {
|
||||
/**
|
||||
* Build a [Matcher] to match the given error code against an error
|
||||
*
|
||||
* @param errorCode the error code
|
||||
* @return a new [Matcher]
|
||||
*/
|
||||
fun build(errorCode: T): Matcher
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler
|
||||
|
||||
class UnknownErrorCodeException(val errorCode: Any) : RuntimeException()
|
||||
@ -1,45 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler.retrofit
|
||||
|
||||
/**
|
||||
* Range class for HTTP status codes
|
||||
*/
|
||||
class Range private constructor(val lowerBound: Int, val upperBound: Int) {
|
||||
|
||||
/**
|
||||
* Checks if the passed httpStatusCode is contained in given range
|
||||
*
|
||||
* @param httpStatusCode the status code to check
|
||||
* @return true if contains, otherwise false
|
||||
*/
|
||||
operator fun contains(httpStatusCode: Int): Boolean {
|
||||
return httpStatusCode in lowerBound..upperBound
|
||||
}
|
||||
|
||||
override fun equals(o: Any?): Boolean {
|
||||
if (this === o) return true
|
||||
if (o == null || javaClass != o.javaClass) return false
|
||||
val range =
|
||||
o as Range
|
||||
return if (lowerBound != range.lowerBound) false else upperBound == range.upperBound
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = lowerBound
|
||||
result = 31 * result + upperBound
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates a Range object with lower and upper bound
|
||||
* @param lowerBound lower limit of Range
|
||||
* @param upperBound upper limit of Range
|
||||
*
|
||||
* @return a Range instance
|
||||
*/
|
||||
@JvmStatic
|
||||
fun of(lowerBound: Int, upperBound: Int): Range {
|
||||
return Range(lowerBound, upperBound)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
package com.hmg.hmgDr.errorhandler.retrofit
|
||||
|
||||
import com.hmg.hmgDr.errorhandler.Matcher
|
||||
import com.hmg.hmgDr.errorhandler.MatcherFactory
|
||||
import retrofit2.adapter.rxjava.HttpException
|
||||
|
||||
object RetrofitMatcherFactory {
|
||||
|
||||
/**
|
||||
* Creates a [MatcherFactory] that checks HTTP statuses
|
||||
*
|
||||
* @return new MatcherFactory for Retrofit Rx HttpException that works with Integer
|
||||
*/
|
||||
@JvmStatic
|
||||
fun create(): MatcherFactory<Int> {
|
||||
return object : MatcherFactory<Int> {
|
||||
override fun build(errorCode: Int): Matcher {
|
||||
return object : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return throwable is HttpException &&
|
||||
throwable.code() == errorCode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [MatcherFactory] that checks if HTTP status is in given [Range]
|
||||
*
|
||||
* @return new MatcherFactory for Retrofit Rx HttpException that works with Range
|
||||
*/
|
||||
@JvmStatic
|
||||
fun createRange(): MatcherFactory<Range> {
|
||||
return object : MatcherFactory<Range> {
|
||||
override fun build(errorCode: Range): Matcher {
|
||||
return object : Matcher {
|
||||
override fun matches(throwable: Throwable): Boolean {
|
||||
return throwable is HttpException &&
|
||||
errorCode.contains(throwable.code())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.hmg.hmgDr.util
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
object DateUtils {
|
||||
|
||||
var simpleDateFormat: SimpleDateFormat = SimpleDateFormat("hh:mm:ss", Locale.ENGLISH)
|
||||
|
||||
fun differentDateTimeBetweenDateAndNow(firstDate: Date): String {
|
||||
val now: Date = Calendar.getInstance().time
|
||||
//1 minute = 60 seconds
|
||||
//1 hour = 60 x 60 = 3600
|
||||
//1 day = 3600 x 24 = 86400
|
||||
|
||||
var different: Long = now.time - firstDate.time
|
||||
|
||||
val secondsInMilli: Long = 1000
|
||||
val minutesInMilli = secondsInMilli * 60
|
||||
val hoursInMilli = minutesInMilli * 60
|
||||
val daysInMilli = hoursInMilli * 24
|
||||
|
||||
val elapsedDays = different / daysInMilli
|
||||
different %= daysInMilli
|
||||
|
||||
val elapsedHours = different / hoursInMilli
|
||||
different %= hoursInMilli
|
||||
|
||||
val elapsedMinutes = different / minutesInMilli
|
||||
different %= minutesInMilli
|
||||
|
||||
val elapsedSeconds = different / secondsInMilli
|
||||
|
||||
val format = "%1$02d:%2$02d" // two digits
|
||||
return String.format(format, elapsedMinutes, elapsedSeconds)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue