diff --git a/android/src/main/java/com/youversion/reactnativesdk/RNBibleReaderViewModule.kt b/android/src/main/java/com/youversion/reactnativesdk/RNBibleReaderViewModule.kt index 2c7d68e..ee12b2f 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/RNBibleReaderViewModule.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/RNBibleReaderViewModule.kt @@ -1,5 +1,6 @@ package com.youversion.reactnativesdk +import com.youversion.reactnativesdk.views.BibleReaderViewProps import com.youversion.reactnativesdk.views.YVPBibleReaderView import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition @@ -8,6 +9,8 @@ class RNBibleReaderViewModule : Module() { override fun definition() = ModuleDefinition { Name("BibleReaderView") - View(YVPBibleReaderView::class) + View("YVPBibleReaderView") { props: BibleReaderViewProps -> + YVPBibleReaderView(props) + } } } diff --git a/android/src/main/java/com/youversion/reactnativesdk/RNBibleTextViewModule.kt b/android/src/main/java/com/youversion/reactnativesdk/RNBibleTextViewModule.kt index e48070d..bcd4e66 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/RNBibleTextViewModule.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/RNBibleTextViewModule.kt @@ -1,15 +1,26 @@ package com.youversion.reactnativesdk +import androidx.compose.runtime.remember +import com.youversion.reactnativesdk.api.VerseTappedEvent +import com.youversion.reactnativesdk.views.BibleTextViewProps import com.youversion.reactnativesdk.views.YVPBibleTextView import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition +import expo.modules.kotlin.viewevent.getValue class RNBibleTextViewModule : Module() { override fun definition() = ModuleDefinition { Name("BibleTextView") - View(YVPBibleTextView::class) { - Events("onTap") + View( + name = "YVPBibleTextView", + events = { Events("onTap") } + ) { props: BibleTextViewProps -> + val onTap by remember { EventDispatcher() } + + YVPBibleTextView(props) { event: VerseTappedEvent -> + onTap(event) + } } } } diff --git a/android/src/main/java/com/youversion/reactnativesdk/RNBibleWidgetViewModule.kt b/android/src/main/java/com/youversion/reactnativesdk/RNBibleWidgetViewModule.kt index 598f985..7014e59 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/RNBibleWidgetViewModule.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/RNBibleWidgetViewModule.kt @@ -1,5 +1,6 @@ package com.youversion.reactnativesdk +import com.youversion.reactnativesdk.views.BibleWidgetViewProps import com.youversion.reactnativesdk.views.YVPBibleWidgetView import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition @@ -8,6 +9,8 @@ class RNBibleWidgetViewModule : Module() { override fun definition() = ModuleDefinition { Name("BibleWidgetView") - View(YVPBibleWidgetView::class) + View("YVPBibleWidgetView") { props: BibleWidgetViewProps -> + YVPBibleWidgetView(props) + } } } diff --git a/android/src/main/java/com/youversion/reactnativesdk/RNSignInWithYouVersionButtonModule.kt b/android/src/main/java/com/youversion/reactnativesdk/RNSignInWithYouVersionButtonModule.kt index 9a5730b..bc1611e 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/RNSignInWithYouVersionButtonModule.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/RNSignInWithYouVersionButtonModule.kt @@ -1,15 +1,27 @@ package com.youversion.reactnativesdk +import androidx.compose.runtime.remember +import com.youversion.reactnativesdk.views.SignInWithYouVersionButtonProps import com.youversion.reactnativesdk.views.YVPSignInWithYouVersionButton import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition +import expo.modules.kotlin.viewevent.getValue class RNSignInWithYouVersionButtonModule : Module() { override fun definition() = ModuleDefinition { Name("SignInWithYouVersionButton") - View(YVPSignInWithYouVersionButton::class) { - Events("onTap") + View( + name = "YVPSignInWithYouVersionButton", + events = { Events("onTap") } + ) { props: SignInWithYouVersionButtonProps -> + val onTap by remember { EventDispatcher() } + + YVPSignInWithYouVersionButton( + props = props + ) { + onTap(Unit) + } } } } \ No newline at end of file diff --git a/android/src/main/java/com/youversion/reactnativesdk/RNVotdViewModule.kt b/android/src/main/java/com/youversion/reactnativesdk/RNVotdViewModule.kt index 34953d6..e771844 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/RNVotdViewModule.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/RNVotdViewModule.kt @@ -1,13 +1,28 @@ package com.youversion.reactnativesdk +import androidx.compose.runtime.remember +import com.youversion.reactnativesdk.views.VotdViewProps import com.youversion.reactnativesdk.views.YVPVotdView import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition +import expo.modules.kotlin.viewevent.getValue class RNVotdViewModule : Module() { override fun definition() = ModuleDefinition { Name("VotdView") - View(YVPVotdView::class) + View( + name = "YVPVotdView", + events = { Events("onSharePress", "onFullChapterPress") } + ) { props: VotdViewProps -> + val onSharePress by remember { EventDispatcher() } + val onFullChapterPress by remember { EventDispatcher() } + + YVPVotdView( + props = props, + onSharePress = { onSharePress(Unit) }, + onFullChapterPress = { onFullChapterPress(Unit) } + ) + } } } diff --git a/android/src/main/java/com/youversion/reactnativesdk/api/YVPRecords.kt b/android/src/main/java/com/youversion/reactnativesdk/api/YVPRecords.kt index c2eebe5..b4889ad 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/api/YVPRecords.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/api/YVPRecords.kt @@ -1,5 +1,6 @@ package com.youversion.reactnativesdk.api +import com.youversion.platform.core.bibles.domain.BibleReference import com.youversion.platform.core.bibles.models.BibleBook import com.youversion.platform.core.bibles.models.BibleChapter import com.youversion.platform.core.bibles.models.BibleVersion @@ -61,6 +62,20 @@ data class LanguageRecord( ) } +data class VerseTappedEvent( + @Field + val bibleReference: BibleReferenceRecord +) : Record { + constructor(bibleReference: BibleReference) : this( + bibleReference = BibleReferenceRecord( + versionId = bibleReference.versionId, + bookUSFM = bibleReference.bookUSFM, + chapter = bibleReference.chapter, + verse = bibleReference.verseStart + ) + ) +} + data class BibleVersionRecord( @Field val id: Int, @@ -155,6 +170,8 @@ data class BibleReferenceRecord( val bookUSFM: String, @Field val chapter: Int, + @Field + val verse: Int? ) : Record data class HighlightRecord( diff --git a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt index fd20704..1a5ed29 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt @@ -1,67 +1,55 @@ package com.youversion.reactnativesdk.views -import android.content.Context import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.Modifier import com.youversion.platform.core.bibles.domain.BibleReference import com.youversion.platform.reader.BibleReader -import expo.modules.kotlin.AppContext -import expo.modules.kotlin.views.ComposableScope import expo.modules.kotlin.views.ComposeProps -import expo.modules.kotlin.views.ExpoComposeView const val DEFAULT_BEREAN_STANDARD_BIBLE_VERSION = 3034 data class BibleReaderViewProps( - val versionId: MutableState = mutableStateOf(null), - val bookUSFM: MutableState = mutableStateOf(null), - val chapter: MutableState = mutableStateOf(null), - val verse: MutableState = mutableStateOf(null), - val verseStart: MutableState = mutableStateOf(null), - val verseEnd: MutableState = mutableStateOf(null), - val appName: MutableState = mutableStateOf(null), - val signInMessage: MutableState = mutableStateOf(null), - val hasReference: MutableState = mutableStateOf(null) + val versionId: Int? = null, + val bookUSFM: String? = null, + val chapter: Int? = null, + val verse: Int? = null, + val verseStart: Int? = null, + val verseEnd: Int? = null, + val appName: String? = null, + val signInMessage: String? = null, + val hasReference: Boolean? = null ) : ComposeProps -class YVPBibleReaderView(context: Context, appContext: AppContext) : - ExpoComposeView(context, appContext, withHostingView = true) { - override val props = BibleReaderViewProps() +@Composable +fun YVPBibleReaderView(props: BibleReaderViewProps) { + BibleReader( + appName = props.appName ?: "", + appSignInMessage = props.signInMessage ?: "", + bibleReference = bibleReference(props), + ) +} - @Composable - override fun ComposableScope.Content() { - BibleReader( - appName = props.appName.value ?: "", - appSignInMessage = props.signInMessage.value ?: "", - bibleReference = bibleReference(), +fun bibleReference(props: BibleReaderViewProps): BibleReference? { + val start = props.verseStart + val end = props.verseEnd + + if (start != null && end != null) { + return BibleReference( + versionId = props.versionId ?: DEFAULT_BEREAN_STANDARD_BIBLE_VERSION, + bookUSFM = props.bookUSFM ?: "JHN", + chapter = props.chapter ?: 1, + verseStart = start, + verseEnd = end ) } - fun bibleReference(): BibleReference? { - val start = props.verseStart.value - val end = props.verseEnd.value - - if (start != null && end != null) { - return BibleReference( - versionId = props.versionId.value ?: DEFAULT_BEREAN_STANDARD_BIBLE_VERSION, - bookUSFM = props.bookUSFM.value ?: "JHN", - chapter = props.chapter.value ?: 1, - verseStart = start, - verseEnd = end - ) - } - - if (props.hasReference.value == true) { - return BibleReference( - versionId = props.versionId.value ?: DEFAULT_BEREAN_STANDARD_BIBLE_VERSION, - bookUSFM = props.bookUSFM.value ?: "JHN", - chapter = props.chapter.value ?: 1, - verse = props.verse.value - ) - } - - return null + if (props.hasReference == true) { + return BibleReference( + versionId = props.versionId ?: DEFAULT_BEREAN_STANDARD_BIBLE_VERSION, + bookUSFM = props.bookUSFM ?: "JHN", + chapter = props.chapter ?: 1, + verse = props.verse + ) } + + return null } diff --git a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt index 5cc2e26..878ebcc 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt @@ -1,61 +1,106 @@ package com.youversion.reactnativesdk.views -import android.content.Context -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import expo.modules.kotlin.AppContext -import expo.modules.kotlin.viewevent.EventDispatcher -import expo.modules.kotlin.views.ComposableScope +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.sp +import com.youversion.platform.core.bibles.domain.BibleReference +import com.youversion.platform.ui.views.BibleText +import com.youversion.platform.ui.views.BibleTextFootnoteMode +import com.youversion.platform.ui.views.BibleTextOptions +import com.youversion.reactnativesdk.api.VerseTappedEvent import expo.modules.kotlin.views.ComposeProps -import expo.modules.kotlin.views.ExpoComposeView data class BibleTextViewProps( - // Styling - val fontFamily: MutableState = mutableStateOf(null), - val fontSize: MutableState = mutableStateOf(16f), - val lineSpacing: MutableState = mutableStateOf(null), - val paragraphSpacing: MutableState = mutableStateOf(null), - val textColor: MutableState = mutableStateOf(null), - val wocColor: MutableState = mutableStateOf(null), - val footnoteMode: MutableState = mutableStateOf("none"), - val renderVerseNumbers: MutableState = mutableStateOf(true), - - // Bible reference - val versionId: MutableState = mutableStateOf(null), - val bookUSFM: MutableState = mutableStateOf(null), - val chapter: MutableState = mutableStateOf(null), - val verse: MutableState = mutableStateOf(null), - val verseStart: MutableState = mutableStateOf(null), - val verseEnd: MutableState = mutableStateOf(null), + val fontFamily: String = "Times New Roman", + val fontSize: Float = 16f, + val lineSpacing: Float? = null, + val paragraphSpacing: Float? = null, + val textColor: Color? = null, + val wocColor: Color? = null, + val footnoteMode: String? = null, + val renderVerseNumbers: Boolean? = true, + + val versionId: Int? = null, + val bookUSFM: String? = null, + val chapter: Int? = null, + val verse: Int? = null, + val verseStart: Int? = null, + val verseEnd: Int? = null, ) : ComposeProps -class YVPBibleTextView(context: Context, appContext: AppContext) : - ExpoComposeView(context, appContext, withHostingView = true) { - - override val props = BibleTextViewProps() - private val onTap by EventDispatcher() - - @Composable - override fun ComposableScope.Content() { - // TODO: Replace with actual BibleText composable when Kotlin SDK is ready - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Text( - text = "BibleTextView placeholder - versionId: ${props.versionId.value}, " + - "book: ${props.bookUSFM.value}, chapter: ${props.chapter.value}", - color = Color.Gray - ) +val defaultTextOptions = BibleTextOptions() + +@Composable +fun YVPBibleTextView(props: BibleTextViewProps, onTap: (event: VerseTappedEvent) -> Unit) { + BibleText( + reference = bibleReference(props), + textOptions = textOptions(props), + onVerseTap = { reference: BibleReference, _: Offset -> + onTap(VerseTappedEvent(reference)) } + ) +} + +fun bibleReference(props: BibleTextViewProps): BibleReference { + if (props.chapter == null) { + throw IllegalStateException("Chapter is required") + } + + if (props.bookUSFM == null) { + throw IllegalStateException("Book is required") + } + + if (props.versionId == null) { + throw IllegalStateException("Version is required") + } + + val start = props.verseStart + val end = props.verseEnd + + if (start != null && end != null) { + return BibleReference( + versionId = props.versionId, + bookUSFM = props.bookUSFM, + chapter = props.chapter, + verseStart = start, + verseEnd = end + ) } + + return BibleReference( + versionId = props.versionId, + bookUSFM = props.bookUSFM, + chapter = props.chapter, + verse = props.verse + ) +} + +fun textOptions(props: BibleTextViewProps): BibleTextOptions { + return BibleTextOptions( + fontFamily = FontFamily.Serif, + fontSize = props.fontSize.sp, + lineSpacing = props.lineSpacing?.sp ?: defaultTextOptions.lineSpacing, + textColor = props.textColor, + wocColor = props.wocColor ?: composeColor(0xFFF04C59), + renderVerseNumbers = props.renderVerseNumbers + ?: defaultTextOptions.renderVerseNumbers, + footnoteMode = footnodeMode(props) + ) } + +fun composeColor(hexColor: Long): Color { + return Color(hexColor) +} + +fun footnodeMode(props: BibleTextViewProps): BibleTextFootnoteMode { + return when (props.footnoteMode) { + "none" -> BibleTextFootnoteMode.NONE + "inline" -> BibleTextFootnoteMode.INLINE + "marker" -> BibleTextFootnoteMode.MARKER + "letters" -> BibleTextFootnoteMode.LETTERS + "image" -> BibleTextFootnoteMode.IMAGE + else -> defaultTextOptions.footnoteMode + } +} \ No newline at end of file diff --git a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt index ad13ec6..1558c93 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt @@ -1,61 +1,84 @@ package com.youversion.reactnativesdk.views -import android.content.Context import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import expo.modules.kotlin.AppContext -import expo.modules.kotlin.views.ComposableScope +import com.youversion.platform.core.bibles.domain.BibleReference +import com.youversion.platform.ui.views.BibleTextOptions +import com.youversion.platform.ui.views.card.BibleCard import expo.modules.kotlin.views.ComposeProps -import expo.modules.kotlin.views.ExpoComposeView data class BibleWidgetViewProps( // Bible reference - val versionId: MutableState = mutableStateOf(null), - val bookUSFM: MutableState = mutableStateOf(null), - val chapter: MutableState = mutableStateOf(null), - val verse: MutableState = mutableStateOf(null), - val verseStart: MutableState = mutableStateOf(null), - val verseEnd: MutableState = mutableStateOf(null), - - val fontSize: MutableState = mutableStateOf(23f), - val colorScheme: MutableState = mutableStateOf(null), + val versionId: Int? = null, + val bookUSFM: String? = null, + val chapter: Int? = null, + val verse: Int? = null, + val verseStart: Int? = null, + val verseEnd: Int? = null, + + val fontSize: Float? = 23f, + val colorScheme: String? = null, ) : ComposeProps -class YVPBibleWidgetView(context: Context, appContext: AppContext) : - ExpoComposeView(context, appContext, withHostingView = true) { - - override val props = BibleWidgetViewProps() - - @Composable - override fun ComposableScope.Content() { - val isDark = when (props.colorScheme.value) { - "dark" -> true - "light" -> false - else -> isSystemInDarkTheme() - } - - // TODO: Replace with actual BibleWidget composable when Kotlin SDK is ready - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Text( - text = "BibleWidgetView placeholder\n" + - "${props.bookUSFM.value} ${props.chapter.value}:${props.verse.value ?: "${props.verseStart.value}-${props.verseEnd.value}"}", - color = if (isDark) Color.White else Color.DarkGray, - fontSize = (props.fontSize.value ?: 23f).sp - ) - } +@Composable +fun YVPBibleWidgetView(props: BibleWidgetViewProps) { + BibleCard( + reference = bibleReference(props), + textOptions = textOptions(props), + modifier = Modifier.fillMaxHeight(), + ) +} + +fun textOptions(props: BibleWidgetViewProps): BibleTextOptions { + if (props.fontSize == null) { + return BibleTextOptions() } + + return BibleTextOptions(fontSize = props.fontSize.sp) } + +fun bibleReference(props: BibleWidgetViewProps): BibleReference { + if (props.chapter == null) { + throw IllegalStateException("Chapter is required") + } + + if (props.bookUSFM == null) { + throw IllegalStateException("Book is required") + } + + if (props.versionId == null) { + throw IllegalStateException("Version is required") + } + + val start = props.verseStart + val end = props.verseEnd + + if (start != null && end != null) { + return BibleReference( + versionId = props.versionId, + bookUSFM = props.bookUSFM, + chapter = props.chapter, + verseStart = start, + verseEnd = end + ) + } + + return BibleReference( + versionId = props.versionId, + bookUSFM = props.bookUSFM, + chapter = props.chapter, + verse = props.verse + ) +} + +@Composable +fun isDark(props: BibleWidgetViewProps): Boolean { + return when (props.colorScheme) { + "dark" -> true + "light" -> false + else -> isSystemInDarkTheme() + } +} \ No newline at end of file diff --git a/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt b/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt index 19ceabe..14037db 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt @@ -1,70 +1,62 @@ package com.youversion.reactnativesdk.views -import android.content.Context import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.graphics.Shape import com.youversion.platform.ui.views.SignInWithYouVersionButton import com.youversion.platform.ui.views.SignInWithYouVersionButtonDefaults import com.youversion.platform.ui.views.SignInWithYouVersionButtonMode -import expo.modules.kotlin.AppContext -import expo.modules.kotlin.views.ComposableScope import expo.modules.kotlin.views.ComposeProps -import expo.modules.kotlin.views.ExpoComposeView data class SignInWithYouVersionButtonProps( - val mode: MutableState = mutableStateOf("full"), - val shape: MutableState = mutableStateOf("capsule"), - val isStroked: MutableState = mutableStateOf(true), - val colorScheme: MutableState = mutableStateOf(null) + val mode: String? = "full", + val shape: String? = "capsule", + val isStroked: Boolean? = true, + val colorScheme: String? = null ) : ComposeProps -class YVPSignInWithYouVersionButton(context: Context, appContext: AppContext) : - ExpoComposeView(context, appContext, withHostingView = true) { - override val props = SignInWithYouVersionButtonProps() -// private val onTap by EventDispatcher() - @Composable - override fun ComposableScope.Content() { - SignInWithYouVersionButton( - mode = mode(), - stroked = stroked(), - shape = shape(), - dark = isDark(), - permissions = { HashSet() } - ) +@Composable +fun YVPSignInWithYouVersionButton( + props: SignInWithYouVersionButtonProps, + onTap: () -> Unit +) { + SignInWithYouVersionButton( + mode = mode(props), + stroked = stroked(props), + shape = shape(props), + dark = isDark(props), + permissions = { HashSet() } + ) +} + +fun mode(props: SignInWithYouVersionButtonProps): SignInWithYouVersionButtonMode { + return when (props.mode) { + "full" -> SignInWithYouVersionButtonMode.FULL + "compact" -> SignInWithYouVersionButtonMode.COMPACT + "iconOnly" -> SignInWithYouVersionButtonMode.ICON_ONLY + else -> SignInWithYouVersionButtonMode.FULL } - - fun mode(): SignInWithYouVersionButtonMode { - return when (props.mode.value) { - "full" -> SignInWithYouVersionButtonMode.FULL - "compact" -> SignInWithYouVersionButtonMode.COMPACT - "iconOnly" -> SignInWithYouVersionButtonMode.ICON_ONLY - else -> SignInWithYouVersionButtonMode.FULL - } - } - - fun stroked(): Boolean { - return props.isStroked.value ?: true +} + +fun stroked(props: SignInWithYouVersionButtonProps): Boolean { + return props.isStroked ?: true +} + +@Composable +fun shape(props: SignInWithYouVersionButtonProps): Shape { + return when (props.shape) { + "capsule" -> SignInWithYouVersionButtonDefaults.capsuleShape + "rectangle" -> SignInWithYouVersionButtonDefaults.rectangleShape + else -> SignInWithYouVersionButtonDefaults.capsuleShape } - - @Composable - fun shape(): Shape { - return when (props.shape.value) { - "capsule" -> SignInWithYouVersionButtonDefaults.capsuleShape - "rectangle" -> SignInWithYouVersionButtonDefaults.rectangleShape - else -> SignInWithYouVersionButtonDefaults.capsuleShape - } - } - - @Composable - fun isDark(): Boolean { - return when (props.colorScheme.value) { - "dark" -> true - "light" -> false - else -> isSystemInDarkTheme() - } +} + +@Composable +fun isDark(props: SignInWithYouVersionButtonProps): Boolean { + return when (props.colorScheme) { + "dark" -> true + "light" -> false + else -> isSystemInDarkTheme() } } \ No newline at end of file diff --git a/android/src/main/java/com/youversion/reactnativesdk/views/YVPVotdView.kt b/android/src/main/java/com/youversion/reactnativesdk/views/YVPVotdView.kt index eed24a9..3abeadc 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPVotdView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPVotdView.kt @@ -1,50 +1,46 @@ package com.youversion.reactnativesdk.views -import android.content.Context import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import expo.modules.kotlin.AppContext -import expo.modules.kotlin.views.ComposableScope +import com.youversion.platform.ui.views.votd.CompactVerseOfTheDay +import com.youversion.platform.ui.views.votd.VerseOfTheDay import expo.modules.kotlin.views.ComposeProps -import expo.modules.kotlin.views.ExpoComposeView data class VotdViewProps( - val bibleVersionId: MutableState = mutableStateOf(3034), - val colorScheme: MutableState = mutableStateOf(null), + val bibleVersionId: Int? = 3034, + val colorScheme: String? = null, + val showIcon: Boolean? = null, + val isCompact: Boolean? = null ) : ComposeProps -class YVPVotdView(context: Context, appContext: AppContext) : - ExpoComposeView(context, appContext, withHostingView = true) { - - override val props = VotdViewProps() - - @Composable - override fun ComposableScope.Content() { - val isDark = when (props.colorScheme.value) { - "dark" -> true - "light" -> false - else -> isSystemInDarkTheme() - } +@Composable +fun YVPVotdView(props: VotdViewProps, onSharePress: () -> Unit, onFullChapterPress: () -> Unit) { + if (props.isCompact == true) { + CompactVerseOfTheDay( + bibleVersionId = props.bibleVersionId ?: 3034, + dark = isDark(props), + showIcon = isIconVisible(props) + ) + } else { + VerseOfTheDay( + bibleVersionId = props.bibleVersionId ?: 3034, + dark = isDark(props), + onShareClick = { onSharePress() }, + onFullChapterClick = { onFullChapterPress() }, + showIcon = isIconVisible(props) + ) + } +} - // TODO: Replace with actual VerseOfTheDay composable when Kotlin SDK is ready - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Text( - text = "VotdView placeholder - versionId: ${props.bibleVersionId.value}", - color = if (isDark) Color.White else Color.DarkGray - ) - } +@Composable +fun isDark(props: VotdViewProps): Boolean { + return when (props.colorScheme) { + "dark" -> true + "light" -> false + else -> isSystemInDarkTheme() } } + +fun isIconVisible(props: VotdViewProps): Boolean { + return props.showIcon ?: true +} diff --git a/example/App.tsx b/example/App.tsx index d970826..da56ec8 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -2,6 +2,7 @@ import { createNativeBottomTabNavigator } from "@react-navigation/bottom-tabs/un import { NavigationContainer } from "@react-navigation/native"; import { YouVersionPlatform } from "@youversion/platform-sdk-reactnative"; import { useEffect } from "react"; +import { Platform } from "react-native"; import { ProfileScreen } from "./src/screens/ProfileScreen"; import { ReaderScreen } from "./src/screens/ReaderScreen"; @@ -24,7 +25,13 @@ export default function App() { component={ReaderScreen} options={{ tabBarLabel: "Bible", - tabBarIcon: { type: "sfSymbol", name: "book.closed.fill" }, + tabBarIcon: + Platform.OS === "ios" + ? { type: "sfSymbol", name: "book.fill" } + : { + type: "image", + source: require("./assets/reader.png"), + }, }} /> diff --git a/example/assets/profile.png b/example/assets/profile.png new file mode 100644 index 0000000..6d0fd2b Binary files /dev/null and b/example/assets/profile.png differ diff --git a/example/assets/reader.png b/example/assets/reader.png new file mode 100644 index 0000000..89d8d97 Binary files /dev/null and b/example/assets/reader.png differ diff --git a/example/assets/votd.png b/example/assets/votd.png new file mode 100644 index 0000000..613475f Binary files /dev/null and b/example/assets/votd.png differ diff --git a/example/assets/widget.png b/example/assets/widget.png new file mode 100644 index 0000000..ae4c0d0 Binary files /dev/null and b/example/assets/widget.png differ diff --git a/src/components/BibleTextView.tsx b/src/components/BibleTextView.tsx index 42d77ea..c281e57 100644 --- a/src/components/BibleTextView.tsx +++ b/src/components/BibleTextView.tsx @@ -1,6 +1,7 @@ -import { Host } from "@expo/ui/swift-ui"; +import { Host as AndroidHost } from "@expo/ui/jetpack-compose"; +import { Host as IosHost } from "@expo/ui/swift-ui"; import { requireNativeView } from "expo"; -import { StyleProp, StyleSheet, ViewStyle } from "react-native"; +import { Platform, StyleProp, StyleSheet, ViewStyle } from "react-native"; import { BibleReference, @@ -11,6 +12,9 @@ import { const NativeView: React.ComponentType = requireNativeView("BibleTextView"); +const PlatformHost = Platform.OS === "ios" ? IosHost : AndroidHost; + +const MATCH_CONTENTS = { vertical: true, horizontal: false }; /** * A minimal text view for displaying a Bible passage. * The component supports font customizations and accepts an `onPress` handler @@ -25,14 +29,17 @@ export function BibleTextView({ ...props }: BibleTextViewProps) { return ( - + onPress?.(e.nativeEvent)} style={styles.component} /> - + ); } diff --git a/src/components/BibleWidgetView.tsx b/src/components/BibleWidgetView.tsx index 67a687f..20a9dd6 100644 --- a/src/components/BibleWidgetView.tsx +++ b/src/components/BibleWidgetView.tsx @@ -1,6 +1,7 @@ -import { Host } from "@expo/ui/swift-ui"; +import { Host as AndroidHost } from "@expo/ui/jetpack-compose"; +import { Host as IosHost } from "@expo/ui/swift-ui"; import { requireNativeView } from "expo"; -import { StyleProp, StyleSheet, ViewStyle } from "react-native"; +import { Platform, StyleProp, StyleSheet, ViewStyle } from "react-native"; import { BibleReference } from "../types"; @@ -9,6 +10,8 @@ const NativeView: React.ComponentType = const MATCH_CONTENTS = { vertical: true, horizontal: false }; +const PlatformHost = Platform.OS === "ios" ? IosHost : AndroidHost; + /** * An opinionated Bible passage display. * It displays the book, chapter and version name above the passage. Below the passage text, it displays copyright information and the YouVersion logo. @@ -20,9 +23,12 @@ export function BibleWidgetView({ ...props }: BibleWidgetViewProps) { return ( - + - + ); } diff --git a/src/components/VotdView.tsx b/src/components/VotdView.tsx index da129b4..acd105d 100644 --- a/src/components/VotdView.tsx +++ b/src/components/VotdView.tsx @@ -1,6 +1,9 @@ -import { Host } from "@expo/ui/swift-ui"; +import { Host as AndroidHost } from "@expo/ui/jetpack-compose"; +import { Host as IosHost } from "@expo/ui/swift-ui"; import { requireNativeView } from "expo"; -import { StyleProp, StyleSheet, ViewStyle } from "react-native"; +import { Platform, StyleProp, StyleSheet, ViewStyle } from "react-native"; + +const PlatformHost = Platform.OS === "ios" ? IosHost : AndroidHost; const NativeView: React.ComponentType = requireNativeView("VotdView"); @@ -13,9 +16,12 @@ export function VotdView({ ...props }: VotdViewProps) { return ( - + - + ); } diff --git a/src/types.ts b/src/types.ts index bd15411..2721f18 100644 --- a/src/types.ts +++ b/src/types.ts @@ -140,9 +140,9 @@ export type BibleReference = export interface OnBibleTextPressEvent { /** A reference to the Bible verse that was pressed */ bibleReference: BibleReferenceVerse; - urlScheme: string; + urlScheme?: string; /** Not implemented yet */ - footnotes: unknown[]; + footnotes?: unknown[]; } export interface LanguageOverview {