Skip to content

Commit

Permalink
fix: refactor public methods for plugins use
Browse files Browse the repository at this point in the history
  • Loading branch information
rhenwinch committed Feb 10, 2024
1 parent 9c779ec commit 8b55566
Show file tree
Hide file tree
Showing 29 changed files with 642 additions and 219 deletions.
4 changes: 2 additions & 2 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 7 additions & 8 deletions app/src/main/kotlin/com/flixclusive/crash/CrashReportSender.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.flixclusive.crash
import android.content.Context
import com.flixclusive.core.ui.common.util.showToast
import com.flixclusive.core.util.common.dispatcher.di.ApplicationScope
import com.flixclusive.core.util.network.POST
import com.flixclusive.core.util.network.asString
import com.flixclusive.core.util.network.HttpMethod
import com.flixclusive.core.util.network.formRequest
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -33,13 +33,12 @@ internal class DefaultCrashReportSender @Inject constructor(
) : CrashReportSender {
override fun send(errorLog: String) {
scope.launch {
val response = client.newCall(
POST(
url = errorReportFormUrl,
data = mapOf("entry.1687138646" to errorLog)
)
val response = client.formRequest(
url = errorReportFormUrl,
method = HttpMethod.POST,
body = mapOf("entry.1687138646" to errorLog)
).execute()
val responseString = response.body?.charStream().asString()
val responseString = response.body?.string()

val isSent = response.isSuccessful
&& (responseString?.contains("form_confirm", true) == true || responseString?.contains("submit another response", true) == true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.flixclusive.crash

import com.flixclusive.core.util.network.POST
import com.flixclusive.core.util.network.asString
import com.flixclusive.core.util.network.HttpMethod
import com.flixclusive.core.util.network.ignoreAllSSLErrors
import com.flixclusive.core.util.network.formRequest
import okhttp3.OkHttpClient
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -39,13 +39,12 @@ class CrashReportSenderTest : CrashReportSender {
}

override fun send(errorLog: String) {
val response = client.newCall(
POST(
url = errorReportFormUrl,
data = mapOf("entry.1687138646" to errorLog)
)
val response = client.formRequest(
url = errorReportFormUrl,
method = HttpMethod.POST,
body = mapOf("entry.1687138646" to errorLog)
).execute()
val responseString = response.body?.charStream().asString()
val responseString = response.body?.string()

assert(
response.isSuccessful
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.flixclusive.core.database.util

import androidx.room.TypeConverter
import com.flixclusive.core.util.json.fromJson
import com.flixclusive.core.util.network.fromJson
import com.flixclusive.model.tmdb.FilmImpl
import com.google.gson.Gson

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.flixclusive.core.database.util

import androidx.room.TypeConverter
import com.flixclusive.core.util.json.fromJson
import com.flixclusive.core.util.network.fromJson
import com.flixclusive.model.database.EpisodeWatched
import com.google.gson.Gson
import java.util.Date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,37 @@ package com.flixclusive.core.util.common.resource
import androidx.annotation.StringRes
import com.flixclusive.core.util.common.ui.UiText

/**
* A sealed class representing a resource that can be in one of three states: Success, Failure, or Loading.
* @param T The type of data held by the resource.
* @property data The data associated with the resource. It's nullable and defaults to null.
* @property error The error associated with the resource. It's nullable and defaults to null.
* @property isLoading Indicates whether the resource is in a loading state. It defaults to false.
*/
sealed class Resource<out T>(
val data: T? = null,
val error: UiText? = null,
val isLoading: Boolean = false,
) {
/**
* Represents a successful state of the resource.
* @param data The data associated with the resource.
*/
class Success<T>(data: T) : Resource<T>(data = data, isLoading = false)

/**
* Represents a failure state of the resource.
* @param error The error associated with the resource.
*/
class Failure(error: UiText?) : Resource<Nothing>(error = error, isLoading = false) {
constructor(@StringRes errorId: Int) : this(UiText.StringResource(errorId))
constructor(error: String?) : this(
if(error.isNullOrEmpty()) null else UiText.StringValue(error)
)
}

/**
* Represents a loading state of the resource.
*/
data object Loading : Resource<Nothing>(isLoading = true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.painterResource

// https://stackoverflow.com/a/75526761
/**
* An icon resource that can represent either a drawable resource ID or an image vector.
* @param drawableId The drawable resource ID. Defaults to null.
* @param imageVector The image vector. Defaults to null.
*/
class IconResource private constructor(
@DrawableRes private val drawableId: Int? = null,
private val imageVector: ImageVector? = null
) {
/**
* Returns the icon resource as a Compose Painter.
* @return The Compose Painter representing the icon resource.
*/
@Composable
fun asPainterResource(): Painter {
drawableId?.let {
Expand All @@ -21,13 +29,26 @@ class IconResource private constructor(
return rememberVectorPainter(image = imageVector!!)
}

/**
* A companion object providing factory methods to create IconResource instances.
*/
companion object {
/**
* Creates an IconResource from a drawable resource ID.
* @param drawableId The drawable resource ID.
* @return The created IconResource.
*/
fun fromDrawableResource(@DrawableRes drawableId: Int): IconResource {
return IconResource(drawableId = drawableId)
}

/**
* Creates an IconResource from an image vector.
* @param imageVector The image vector.
* @return The created IconResource.
*/
fun fromImageVector(imageVector: ImageVector?): IconResource {
return IconResource(imageVector = imageVector)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,42 @@ import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource

/**
* A sealed class representing text that can either be a string value or a string resource.
*/
sealed class UiText {
/**
* Represents a string value.
* @param str The string value.
*/
data class StringValue(val str: String) : UiText()

/**
* Represents a string resource.
* @param stringId The string resource ID.
* @param args Optional arguments to format the string resource.
*/
class StringResource(
@StringRes val stringId: Int,
vararg val args: Any,
) : UiText()

/**
* Returns the text as a string.
* @param context The context used to retrieve string resources.
* @return The text as a string.
*/
fun asString(context: Context): String {
return when (this) {
is StringValue -> str
is StringResource -> context.getString(stringId, *args)
}
}

/**
* Returns the text as a string for Composable functions.
* @return The text as a string.
*/
@Composable
fun asString(): String {
return when (this) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,68 @@
package com.flixclusive.core.util.coroutines

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

/**
*
* Fast list iteration:
* https://www.linkedin.com/pulse/faster-list-iteration-using-kotlin-coroutines-elyes-mansour
*
* */
* Asynchronously maps the elements of the iterable using the specified suspending function [mapper].
* @param mapper The suspending function to apply to each element.
* @return A list containing the results of applying the [mapper] function to each element.
*/
suspend fun <T, R> Iterable<T>.mapAsync(
mapper: suspend (T) -> R
): List<R> = coroutineScope { map { async { mapper(it) } }.awaitAll() }

/**
*
* Fast list iteration with index
* */
* Asynchronously maps the elements of the iterable with their index using the specified suspending function [mapper].
* @param mapper The suspending function to apply to each indexed element.
* @return A list containing the results of applying the [mapper] function to each indexed element.
*/
suspend fun <T, R> Iterable<T>.mapIndexedAsync(
mapper: suspend (Int, T) -> R
): List<R> = coroutineScope { mapIndexed { i, item -> async { mapper(i, item) } }.awaitAll() }


/**
*
* From Cloudstream `argamap`, aims to call
* multiple suspend functions asynchronously
*
* https://github.com/recloudstream/cloudstream/blob/9d3b2ba3d2497e3a494f87b88b41687df7f5223a/app/src/main/java/com/lagradost/cloudstream3/ParCollections.kt#L76
*
* */
* Executes multiple suspend functions asynchronously and waits for all to complete.
* @param transforms The suspend functions to execute asynchronously.
* @return A list containing the results of all the suspend functions.
*/
fun <R> asyncCalls(
vararg transforms: suspend () -> R,
) = runBlocking {
transforms.map {
async { it.invoke() }
}.awaitAll()
}
}

private val ioCoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)


/**
* Launches a coroutine in the IO coroutine scope.
* @param block The suspending lambda to execute in the IO coroutine scope.
* @return A [Job] object representing the coroutine job.
*/
fun ioLaunch(block: suspend () -> Unit): Job {
return ioCoroutineScope.launch {
block()
}
}

/**
* Calls the specified suspending function in the IO dispatcher.
* @param block The suspending lambda to execute.
* @return The result of the suspending function.
*/
suspend fun <T> ioCall(block: suspend () -> T): T {
return withContext(Dispatchers.IO) {
block()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import javax.net.ssl.SSLException


/**
*
* Catches all internet-related exceptions
* and returns the message.
*
* */
* Catches exceptions related to internet operations and converts them into a [Resource.Failure] object.
* @return A [Resource.Failure] object with an appropriate error message.
*/
fun Exception.catchInternetRelatedException(): Resource.Failure {
val defaultMessage = localizedMessage ?: message ?: "Unknown error occurred"
errorLog(message = defaultMessage)

val error = when (this) {
return when (this) {
is SocketTimeoutException -> Resource.Failure(R.string.connection_timeout)
is ConnectException, is UnknownHostException -> Resource.Failure(R.string.connection_failed)
is HttpException -> {
Expand All @@ -37,21 +35,22 @@ fun Exception.catchInternetRelatedException(): Resource.Failure {
errorLog(defaultMessage)
Resource.Failure(defaultMessage)
}
}.also {
errorLog(stackTraceToString())
}

errorLog(stackTraceToString())
return error
}

/**
* Executes the provided lambda [unsafeCall] safely, catching any exceptions and logging them.
*
* Converts a possible unsafe call to a safe call.
*
* */
inline fun <T> safeCall(unsafeCall: () -> T?)
= try {
* @param unsafeCall The lambda representing the possibly unsafe call.
* @return The result of the lambda if it executes successfully, otherwise null.
*/
inline fun <T> safeCall(unsafeCall: () -> T?): T? {
return try {
unsafeCall()
} catch (e: Exception) {
errorLog(e.stackTraceToString())
null
}
}
}

This file was deleted.

Loading

0 comments on commit 8b55566

Please sign in to comment.