diff --git a/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt b/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt index 57737bc..6c5f067 100644 --- a/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt +++ b/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt @@ -3,20 +3,34 @@ package dev.datlag.aniflow.other import android.content.ContentProviderClient import android.content.ContentResolver import android.content.Context +import android.content.pm.PackageManager import android.net.Uri +import android.os.Build +import dev.datlag.tooling.scopeCatching import io.github.aakira.napier.Napier actual class BurningSeriesResolver( + private val packageManager: PackageManager, private val episodeClient: ContentProviderClient?, private val seriesClient: ContentProviderClient? ) { - - constructor(contentResolver: ContentResolver) : this( + constructor(packageManager: PackageManager, contentResolver: ContentResolver) : this( + packageManager = packageManager, episodeClient = contentResolver.acquireContentProviderClient(episodesContentUri), seriesClient = contentResolver.acquireContentProviderClient(seriesContentUri) ) - constructor(context: Context) : this(context.contentResolver) + constructor(context: Context) : this(context.packageManager, context.contentResolver) + + actual val isAvailable: Boolean + get() = scopeCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager.getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(0)) + } else { + packageManager.getApplicationInfo(packageName, 0) + } + true + }.getOrNull() ?: false actual fun resolveWatchedEpisodes(): Set { if (episodeClient == null) { @@ -118,6 +132,7 @@ actual class BurningSeriesResolver( } companion object { + val packageName = "dev.datlag.burningseries" val seriesContentUri = Uri.parse("content://dev.datlag.burningseries.provider/series") val episodesContentUri = Uri.parse("content://dev.datlag.burningseries.provider/episodes") } diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt index 0097c3d..024fd96 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt @@ -1,6 +1,7 @@ package dev.datlag.aniflow.other expect class BurningSeriesResolver { + val isAvailable: Boolean fun resolveWatchedEpisodes(): Set fun resolveByName(english: String?, romaji: String?) diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/custom/EditFAB.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/custom/EditFAB.kt index 8619929..409d989 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/custom/EditFAB.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/custom/EditFAB.kt @@ -3,10 +3,8 @@ package dev.datlag.aniflow.ui.custom import androidx.compose.animation.* import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add @@ -17,12 +15,18 @@ import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.unit.dp +import dev.datlag.aniflow.SharedRes +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource @Composable fun EditFAB( displayAdd: Boolean = false, + bsAvailable: Boolean = false, + onBS: () -> Unit, onRate: () -> Unit, onProgress: () -> Unit ) { @@ -86,6 +90,35 @@ fun EditFAB( ) } } + AnimatedVisibility( + visible = showOtherFABs && bsAvailable, + enter = scaleIn( + animationSpec = bouncySpring(), + transformOrigin = TransformOrigin(1F, 0.5F) + ) + fadeIn( + animationSpec = bouncySpring() + ), + exit = scaleOut( + transformOrigin = TransformOrigin(1F, 0.5F) + ) + fadeOut( + animationSpec = bouncySpring() + ) + ) { + LabelFAB( + label = stringResource(SharedRes.strings.bs), + onClick = { + showOtherFABs = false + onBS() + } + ) { + Image( + modifier = Modifier.size(24.dp), + painter = painterResource(SharedRes.images.bs), + contentDescription = stringResource(SharedRes.strings.bs), + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + } + } FloatingActionButton( onClick = { diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt index f053fdb..e1c93e4 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt @@ -31,6 +31,8 @@ interface MediumComponent : ContentHolderComponent { val alreadyAdded: StateFlow val trailer: StateFlow + val bsAvailable: Boolean + fun back() override fun dismissContent() { back() diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreen.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreen.kt index 9ea69d6..d4ad6a5 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreen.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreen.kt @@ -212,6 +212,10 @@ fun MediumScreen(component: MediumComponent) { if (!notReleased) { EditFAB( displayAdd = !alreadyAdded, + bsAvailable = component.bsAvailable, + onBS = { + + }, onRate = { component.rate { ratingState.show() diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt index 6bcc8cb..317e659 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt @@ -303,6 +303,9 @@ class MediumScreenComponent( private val characterStateMachine by di.instance() private val burningSeriesResolver by di.instance() + override val bsAvailable: Boolean + get() = burningSeriesResolver.isAvailable + init { launchIO { title.mapNotNull { it.english to it.romaji }.collect { (english, romaji) -> diff --git a/composeApp/src/commonMain/moko-resources/base/strings.xml b/composeApp/src/commonMain/moko-resources/base/strings.xml index 12bc249..c3db814 100644 --- a/composeApp/src/commonMain/moko-resources/base/strings.xml +++ b/composeApp/src/commonMain/moko-resources/base/strings.xml @@ -23,4 +23,5 @@ Score Translate Description + Burning-Series diff --git a/composeApp/src/commonMain/moko-resources/images/bs.svg b/composeApp/src/commonMain/moko-resources/images/bs.svg new file mode 100644 index 0000000..70f981a --- /dev/null +++ b/composeApp/src/commonMain/moko-resources/images/bs.svg @@ -0,0 +1,4 @@ + + + + diff --git a/composeApp/src/iosMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.ios.kt b/composeApp/src/iosMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.ios.kt index 1ce1092..c4ff0bc 100644 --- a/composeApp/src/iosMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.ios.kt +++ b/composeApp/src/iosMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.ios.kt @@ -1,6 +1,10 @@ package dev.datlag.aniflow.other actual class BurningSeriesResolver { + + actual val isAvailable: Boolean + get() = false + actual fun resolveWatchedEpisodes(): Set { // ToDo("Check if something like content provider exists") return emptySet()