Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -8,6 +9,8 @@ class RNBibleReaderViewModule : Module() {
override fun definition() = ModuleDefinition {
Name("BibleReaderView")

View(YVPBibleReaderView::class)
View("YVPBibleReaderView") { props: BibleReaderViewProps ->
YVPBibleReaderView(props)
}
}
}
Original file line number Diff line number Diff line change
@@ -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<VerseTappedEvent>() }

YVPBibleTextView(props) { event: VerseTappedEvent ->
onTap(event)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -8,6 +9,8 @@ class RNBibleWidgetViewModule : Module() {
override fun definition() = ModuleDefinition {
Name("BibleWidgetView")

View(YVPBibleWidgetView::class)
View("YVPBibleWidgetView") { props: BibleWidgetViewProps ->
YVPBibleWidgetView(props)
}
}
}
Original file line number Diff line number Diff line change
@@ -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<Unit>() }

YVPSignInWithYouVersionButton(
props = props
) {
onTap(Unit)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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<Unit>() }
val onFullChapterPress by remember { EventDispatcher<Unit>() }

YVPVotdView(
props = props,
onSharePress = { onSharePress(Unit) },
onFullChapterPress = { onFullChapterPress(Unit) }
)
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -155,6 +170,8 @@ data class BibleReferenceRecord(
val bookUSFM: String,
@Field
val chapter: Int,
@Field
val verse: Int?
) : Record

data class HighlightRecord(
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -26,42 +21,37 @@ data class BibleReaderViewProps(
val hasReference: MutableState<Boolean?> = mutableStateOf(null)
) : ComposeProps

class YVPBibleReaderView(context: Context, appContext: AppContext) :
ExpoComposeView<BibleReaderViewProps>(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
}
Original file line number Diff line number Diff line change
@@ -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<String?> = mutableStateOf(null),
val fontSize: MutableState<Float?> = mutableStateOf(16f),
val fontFamily: MutableState<String> = mutableStateOf("Times New Roman"),
val fontSize: MutableState<Float> = mutableStateOf(16f),
val lineSpacing: MutableState<Float?> = mutableStateOf(null),
val paragraphSpacing: MutableState<Float?> = mutableStateOf(null),
val textColor: MutableState<Int?> = mutableStateOf(null),
val wocColor: MutableState<Int?> = mutableStateOf(null),
val footnoteMode: MutableState<String?> = mutableStateOf("none"),
val textColor: MutableState<Color?> = mutableStateOf(null),
val wocColor: MutableState<Color?> = mutableStateOf(null),
val footnoteMode: MutableState<String?> = mutableStateOf(null),
val renderVerseNumbers: MutableState<Boolean?> = mutableStateOf(true),

// Bible reference
val versionId: MutableState<Int?> = mutableStateOf(null),
val bookUSFM: MutableState<String?> = mutableStateOf(null),
val chapter: MutableState<Int?> = mutableStateOf(null),
Expand All @@ -37,25 +32,77 @@ data class BibleTextViewProps(
val verseEnd: MutableState<Int?> = mutableStateOf(null),
) : ComposeProps

class YVPBibleTextView(context: Context, appContext: AppContext) :
ExpoComposeView<BibleTextViewProps>(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))
}
)
}
Comment on lines +37 to +46
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 onTap callback is never forwarded to BibleText

The onTap: () -> Unit parameter is accepted by YVPBibleTextView but is silently dropped — it is never passed to the underlying BibleText composable. As a result, the onTap event wired up in RNBibleTextViewModule will never fire for JS consumers.

If BibleText exposes a tap/click parameter, it should be passed through here. If it doesn't, this parameter (and the corresponding Events("onTap") declaration in the module) should be removed until the SDK supports it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sidorchukandrew I think this is legit

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about implementing it in this PR because of some difference between what Kotlin and Swift have, but I've decided to add at least the base here: e89f49a


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
}
}
Loading