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..635f0fd 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleReaderView.kt @@ -1,16 +1,11 @@ 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 @@ -26,42 +21,37 @@ data class BibleReaderViewProps( val hasReference: MutableState = mutableStateOf(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.value ?: "", + appSignInMessage = props.signInMessage.value ?: "", + 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.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 ) } - 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.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 } 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 46159f0..dc9d779 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleTextView.kt @@ -1,34 +1,29 @@ 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 fontFamily: MutableState = mutableStateOf("Times New Roman"), + 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 textColor: MutableState = mutableStateOf(null), + val wocColor: MutableState = mutableStateOf(null), + val footnoteMode: MutableState = mutableStateOf(null), val renderVerseNumbers: MutableState = mutableStateOf(true), - // Bible reference val versionId: MutableState = mutableStateOf(null), val bookUSFM: MutableState = mutableStateOf(null), val chapter: MutableState = mutableStateOf(null), @@ -37,25 +32,77 @@ data class BibleTextViewProps( val verseEnd: MutableState = mutableStateOf(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.value == null) { + throw IllegalStateException("Chapter is required") + } + + if (props.bookUSFM.value == null) { + throw IllegalStateException("Book is required") } + + if (props.versionId.value == null) { + throw IllegalStateException("Version is required") + } + + val start = props.verseStart.value + val end = props.verseEnd.value + + if (start != null && end != null) { + return BibleReference( + versionId = props.versionId.value!!, + bookUSFM = props.bookUSFM.value!!, + chapter = props.chapter.value!!, + verseStart = start, + verseEnd = end + ) + } + + return BibleReference( + versionId = props.versionId.value!!, + bookUSFM = props.bookUSFM.value!!, + chapter = props.chapter.value!!, + verse = props.verse.value + ) +} + +fun textOptions(props: BibleTextViewProps): BibleTextOptions { + return BibleTextOptions( + fontFamily = FontFamily.Serif, + fontSize = props.fontSize.value.sp, + lineSpacing = props.lineSpacing.value?.sp ?: defaultTextOptions.lineSpacing, + textColor = props.textColor.value, + wocColor = props.wocColor.value ?: composeColor(0xFFF04C59), + renderVerseNumbers = props.renderVerseNumbers.value + ?: defaultTextOptions.renderVerseNumbers, + footnoteMode = footnodeMode(props) + ) } + +fun composeColor(hexColor: Long): Color { + return Color(hexColor) +} + +fun footnodeMode(props: BibleTextViewProps): BibleTextFootnoteMode { + return when (props.footnoteMode.value) { + "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..52b2e81 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPBibleWidgetView.kt @@ -1,22 +1,16 @@ 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 @@ -31,31 +25,62 @@ data class BibleWidgetViewProps( val colorScheme: MutableState = mutableStateOf(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.value == null) { + return BibleTextOptions() + } + + return BibleTextOptions(fontSize = props.fontSize.value!!.sp) +} + +fun bibleReference(props: BibleWidgetViewProps): BibleReference { + if (props.chapter.value == null) { + throw IllegalStateException("Chapter is required") + } + + if (props.bookUSFM.value == null) { + throw IllegalStateException("Book is required") } + + if (props.versionId.value == null) { + throw IllegalStateException("Version is required") + } + + val start = props.verseStart.value + val end = props.verseEnd.value + + if (start != null && end != null) { + return BibleReference( + versionId = props.versionId.value!!, + bookUSFM = props.bookUSFM.value!!, + chapter = props.chapter.value!!, + verseStart = start, + verseEnd = end + ) + } + + return BibleReference( + versionId = props.versionId.value!!, + bookUSFM = props.bookUSFM.value!!, + chapter = props.chapter.value!!, + verse = props.verse.value + ) } + +@Composable +fun isDark(props: BibleWidgetViewProps): Boolean { + return when (props.colorScheme.value) { + "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..bf4aa8d 100644 --- a/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt +++ b/android/src/main/java/com/youversion/reactnativesdk/views/YVPSignInWithYouVersionButton.kt @@ -1,6 +1,5 @@ package com.youversion.reactnativesdk.views -import android.content.Context import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -9,10 +8,7 @@ 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"), @@ -21,50 +17,48 @@ data class SignInWithYouVersionButtonProps( val colorScheme: MutableState = mutableStateOf(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(): SignInWithYouVersionButtonMode { - return when (props.mode.value) { - "full" -> SignInWithYouVersionButtonMode.FULL - "compact" -> SignInWithYouVersionButtonMode.COMPACT - "iconOnly" -> SignInWithYouVersionButtonMode.ICON_ONLY - else -> SignInWithYouVersionButtonMode.FULL - } +fun mode(props: SignInWithYouVersionButtonProps): 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.value ?: true +} - @Composable - fun shape(): Shape { - return when (props.shape.value) { - "capsule" -> SignInWithYouVersionButtonDefaults.capsuleShape - "rectangle" -> SignInWithYouVersionButtonDefaults.rectangleShape - else -> SignInWithYouVersionButtonDefaults.capsuleShape - } +@Composable +fun shape(props: SignInWithYouVersionButtonProps): 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.value) { + "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..5450513 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,48 @@ 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 showIcon: MutableState = mutableStateOf(null), + val isCompact: MutableState = mutableStateOf(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.value == true) { + CompactVerseOfTheDay( + bibleVersionId = props.bibleVersionId.value ?: 3034, + dark = isDark(props), + showIcon = isIconVisible(props) + ) + } else { + VerseOfTheDay( + bibleVersionId = props.bibleVersionId.value ?: 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.value) { + "dark" -> true + "light" -> false + else -> isSystemInDarkTheme() } } + +fun isIconVisible(props: VotdViewProps): Boolean { + return props.showIcon.value ?: 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 ( - + - + ); }