From 943d6de7e2d7e5061d213f25913c79e984c46ff8 Mon Sep 17 00:00:00 2001 From: ashb155 Date: Tue, 24 Mar 2026 12:21:50 +0530 Subject: [PATCH 1/4] - conjugate about screen --- .../java/be/scri/helpers/ui/ShareHelper.kt | 19 ++++++++--- .../be/scri/ui/screens/about/AboutScreen.kt | 8 ++++- .../be/scri/ui/screens/about/AboutUtil.kt | 32 +++++++++++++++---- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt b/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt index 9031a1063..3c07bcced 100644 --- a/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt +++ b/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt @@ -14,7 +14,7 @@ interface ShareHelperInterface { * * @param context The Android context used to perform the share action. */ - fun shareScribe(context: Context) + fun shareScribe(context: Context, isConjugateApp: Boolean = false) } /** Implementation of ShareHelperInterface to handle sharing a scribe. */ @@ -24,14 +24,25 @@ class ShareHelperImpl : ShareHelperInterface { * * @param context The context from which to launch the share intent. */ - override fun shareScribe(context: Context) { + override fun shareScribe(context: Context, isConjugateApp: Boolean) { + val shareText = if (isConjugateApp) { + "Check out Scribe Conjugate!" + } else { + "Check out Scribe!" + } val sendIntent = Intent().apply { action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_TEXT, "Check out Scribe!") + putExtra(Intent.EXTRA_TEXT, shareText) type = "text/plain" } - val shareIntent = Intent.createChooser(sendIntent, "Share Scribe via…") + + val shareTitle = if (isConjugateApp){ + "Share Scribe Conjugate via…" + } else{ + "Share Scribe via…" + } + val shareIntent = Intent.createChooser(sendIntent, shareTitle) context.startActivity(shareIntent) } } diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt b/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt index f5d18c700..535a78cc6 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt @@ -16,6 +16,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import be.scri.R +import be.scri.helpers.AppFlavor +import be.scri.helpers.FlavorProvider import be.scri.helpers.ui.HintUtils import be.scri.ui.common.ScribeBaseScreen import be.scri.ui.common.components.ItemCardContainerWithTitle @@ -36,6 +38,8 @@ fun AboutScreen( context: Context, modifier: Modifier = Modifier, ) { + + val isConjugateApp = FlavorProvider.get() == AppFlavor.CONJUGATE val scrollState = rememberScrollState() val communityList = @@ -43,8 +47,9 @@ fun AboutScreen( onWikimediaAndScribeClick = { onWikiClick() }, - onShareScribeClick = { AboutUtil.onShareScribeClick(context) }, + onShareScribeClick = { AboutUtil.onShareScribeClick(context, isConjugateApp) }, context = context, + isConjugateApp = isConjugateApp, ) val feedbackAndSupportList = @@ -56,6 +61,7 @@ fun AboutScreen( resetHints() }, context = context, + isConjugateApp = isConjugateApp, ) val legalItemsList = diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt index c25e25589..b88a227eb 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt @@ -39,6 +39,7 @@ fun buildCommunityList( context: Context, onShareScribeClick: () -> Unit, onWikimediaAndScribeClick: () -> Unit, + isConjugateApp: Boolean = false, ): List = listOf( ScribeItem.ExternalLinkItem( @@ -63,7 +64,11 @@ fun buildCommunityList( ), ScribeItem.ExternalLinkItem( leadingIcon = R.drawable.share_icon, - title = R.string.i18n_app_about_community_share_scribe, + title = if (isConjugateApp) { + R.string.i18n_app_about_community_share_conjugate + } else { + R.string.i18n_app_about_community_share_scribe + }, trailingIcon = R.drawable.external_link, url = null, onClick = { onShareScribeClick() }, @@ -110,11 +115,16 @@ fun feedbackAndSupportList( onRateScribeClick: () -> Unit, onMailClick: () -> Unit, onResetHintsClick: () -> Unit, + isConjugateApp: Boolean = false, ): List = listOf( ScribeItem.ExternalLinkItem( leadingIcon = R.drawable.star, - title = R.string.i18n_app_about_feedback_rate_scribe, + title = if (isConjugateApp) { + R.string.i18n_app_about_feedback_rate_conjugate + } else { + R.string.i18n_app_about_feedback_rate_scribe + }, trailingIcon = R.drawable.external_link, url = null, onClick = { onRateScribeClick() }, @@ -191,8 +201,8 @@ object AboutUtil { * * @param context Context used to launch the sharing intent. */ - fun onShareScribeClick(context: Context) { - shareHelper.shareScribe(context) + fun onShareScribeClick(context: Context, isConjugateApp: Boolean = false) { + shareHelper.shareScribe(context, isConjugateApp) } /** @@ -227,10 +237,16 @@ object AboutUtil { onWikimediaAndScribeClick: () -> Unit, onShareScribeClick: () -> Unit, context: Context, + isConjugateApp: Boolean = false, ): ScribeItemList = - remember { + remember(isConjugateApp) { ScribeItemList( - items = buildCommunityList(context, onShareScribeClick, onWikimediaAndScribeClick), + items = buildCommunityList( + context, + onShareScribeClick, + onWikimediaAndScribeClick, + isConjugateApp + ), ) } @@ -250,8 +266,9 @@ object AboutUtil { onMailClick: () -> Unit, onResetHintsClick: () -> Unit, context: Context, + isConjugateApp: Boolean = false, ): ScribeItemList = - remember { + remember(isConjugateApp) { ScribeItemList( items = feedbackAndSupportList( @@ -259,6 +276,7 @@ object AboutUtil { onRateScribeClick, onMailClick, onResetHintsClick, + isConjugateApp, ), ) } From 2f1fad7de96bab72b37f406d33d73342eae09cb9 Mon Sep 17 00:00:00 2001 From: ashb155 Date: Tue, 24 Mar 2026 18:48:56 +0530 Subject: [PATCH 2/4] - conjugate nav bar fix and document param comments --- .../java/be/scri/activities/MainActivity.kt | 27 ++++++++++++++++--- .../be/scri/ui/screens/about/AboutUtil.kt | 5 ++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/src/conjugate/java/be/scri/activities/MainActivity.kt b/app/src/conjugate/java/be/scri/activities/MainActivity.kt index ca54f9859..9254eb621 100644 --- a/app/src/conjugate/java/be/scri/activities/MainActivity.kt +++ b/app/src/conjugate/java/be/scri/activities/MainActivity.kt @@ -6,18 +6,20 @@ package be.scri.activities +import android.os.Build import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatDelegate -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.core.view.WindowCompat import androidx.navigation.compose.rememberNavController import be.scri.ScribeApp import be.scri.helpers.PreferencesHelper @@ -38,7 +40,8 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) AppCompatDelegate.setDefaultNightMode(PreferencesHelper.getUserDarkModePreference(this)) - enableEdgeToEdge() + val isDark = PreferencesHelper.getUserDarkModePreference(this) == AppCompatDelegate.MODE_NIGHT_YES + applyNavigationBarStyle(isDark) setContent { val context = LocalContext.current @@ -76,6 +79,7 @@ class MainActivity : ComponentActivity() { ) isDarkMode.value = darkMode + applyNavigationBarStyle(darkMode) } ScribeTheme( @@ -98,9 +102,26 @@ class MainActivity : ComponentActivity() { }, context = context, navController = navController, - modifier = Modifier.navigationBarsPadding(), + modifier = Modifier, ) } } } + + private fun applyNavigationBarStyle(isDark: Boolean) { + enableEdgeToEdge( + navigationBarStyle = + if (isDark) { + SystemBarStyle.dark(android.graphics.Color.BLACK) + } else { + SystemBarStyle.light(android.graphics.Color.WHITE, android.graphics.Color.WHITE) + }, + ) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + window.isNavigationBarContrastEnforced = false + } + WindowCompat.getInsetsController(window, window.decorView).apply { + isAppearanceLightNavigationBars = !isDark + } + } } diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt index b88a227eb..b5efbe911 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt @@ -33,6 +33,7 @@ object ExternalLinks { * @param context Context to launch intents for opening URLs. * @param onShareScribeClick Callback invoked when the "Share Scribe" item is clicked. * @param onWikimediaAndScribeClick Callback invoked when the Wikimedia item is clicked. + * @param isConjugateApp Flag indicating flavor * @return A list of [ScribeItem.ExternalLinkItem] representing community links and actions. */ fun buildCommunityList( @@ -108,6 +109,7 @@ fun getLegalItemSpecs(): List = * @param onRateScribeClick Callback invoked when user selects "Rate Scribe". * @param onMailClick Callback invoked when user wants to send feedback email. * @param onResetHintsClick Callback invoked to reset onboarding hints. + * @param isConjugateApp Flag indicating flavor * @return A list of [ScribeItem.ExternalLinkItem] for feedback and support options. */ fun feedbackAndSupportList( @@ -200,6 +202,7 @@ object AboutUtil { * Shares the Scribe app via the system's share sheet. * * @param context Context used to launch the sharing intent. + * @param isConjugateApp Flag indicating flavor */ fun onShareScribeClick(context: Context, isConjugateApp: Boolean = false) { shareHelper.shareScribe(context, isConjugateApp) @@ -229,6 +232,7 @@ object AboutUtil { * @param onWikimediaAndScribeClick Callback invoked when Wikimedia link is clicked. * @param onShareScribeClick Callback invoked when Share Scribe link is clicked. * @param context Android context to open URLs. + * @param isConjugateApp Flag indicating flavor * * @return A [ScribeItemList] wrapping community external links. */ @@ -257,6 +261,7 @@ object AboutUtil { * @param onMailClick Callback to open email intent. * @param onResetHintsClick Callback to reset onboarding hints. * @param context Android context used to launch external intents. + * @param isConjugateApp Flag indicating flavor * * @return A [ScribeItemList] wrapping feedback and support options. */ From 58234bbd79dde6c21c20ef54f3efbecea195faa5 Mon Sep 17 00:00:00 2001 From: ashb155 Date: Tue, 24 Mar 2026 21:14:18 +0530 Subject: [PATCH 3/4] - ktlint formatting fix --- .../java/be/scri/helpers/ui/ShareHelper.kt | 32 +++++++++----- .../be/scri/ui/screens/about/AboutScreen.kt | 1 - .../be/scri/ui/screens/about/AboutUtil.kt | 44 +++++++++++-------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt b/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt index 3c07bcced..4e914dfee 100644 --- a/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt +++ b/app/src/main/java/be/scri/helpers/ui/ShareHelper.kt @@ -14,7 +14,10 @@ interface ShareHelperInterface { * * @param context The Android context used to perform the share action. */ - fun shareScribe(context: Context, isConjugateApp: Boolean = false) + fun shareScribe( + context: Context, + isConjugateApp: Boolean = false, + ) } /** Implementation of ShareHelperInterface to handle sharing a scribe. */ @@ -24,12 +27,16 @@ class ShareHelperImpl : ShareHelperInterface { * * @param context The context from which to launch the share intent. */ - override fun shareScribe(context: Context, isConjugateApp: Boolean) { - val shareText = if (isConjugateApp) { - "Check out Scribe Conjugate!" - } else { - "Check out Scribe!" - } + override fun shareScribe( + context: Context, + isConjugateApp: Boolean, + ) { + val shareText = + if (isConjugateApp) { + "Check out Scribe Conjugate!" + } else { + "Check out Scribe!" + } val sendIntent = Intent().apply { action = Intent.ACTION_SEND @@ -37,11 +44,12 @@ class ShareHelperImpl : ShareHelperInterface { type = "text/plain" } - val shareTitle = if (isConjugateApp){ - "Share Scribe Conjugate via…" - } else{ - "Share Scribe via…" - } + val shareTitle = + if (isConjugateApp) { + "Share Scribe Conjugate via…" + } else { + "Share Scribe via…" + } val shareIntent = Intent.createChooser(sendIntent, shareTitle) context.startActivity(shareIntent) } diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt b/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt index 535a78cc6..efa44720a 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt @@ -38,7 +38,6 @@ fun AboutScreen( context: Context, modifier: Modifier = Modifier, ) { - val isConjugateApp = FlavorProvider.get() == AppFlavor.CONJUGATE val scrollState = rememberScrollState() diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt index b5efbe911..67e0a637e 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt @@ -65,11 +65,12 @@ fun buildCommunityList( ), ScribeItem.ExternalLinkItem( leadingIcon = R.drawable.share_icon, - title = if (isConjugateApp) { - R.string.i18n_app_about_community_share_conjugate - } else { - R.string.i18n_app_about_community_share_scribe - }, + title = + if (isConjugateApp) { + R.string.i18n_app_about_community_share_conjugate + } else { + R.string.i18n_app_about_community_share_scribe + }, trailingIcon = R.drawable.external_link, url = null, onClick = { onShareScribeClick() }, @@ -122,11 +123,12 @@ fun feedbackAndSupportList( listOf( ScribeItem.ExternalLinkItem( leadingIcon = R.drawable.star, - title = if (isConjugateApp) { - R.string.i18n_app_about_feedback_rate_conjugate - } else { - R.string.i18n_app_about_feedback_rate_scribe - }, + title = + if (isConjugateApp) { + R.string.i18n_app_about_feedback_rate_conjugate + } else { + R.string.i18n_app_about_feedback_rate_scribe + }, trailingIcon = R.drawable.external_link, url = null, onClick = { onRateScribeClick() }, @@ -204,7 +206,10 @@ object AboutUtil { * @param context Context used to launch the sharing intent. * @param isConjugateApp Flag indicating flavor */ - fun onShareScribeClick(context: Context, isConjugateApp: Boolean = false) { + fun onShareScribeClick( + context: Context, + isConjugateApp: Boolean = false, + ) { shareHelper.shareScribe(context, isConjugateApp) } @@ -232,7 +237,7 @@ object AboutUtil { * @param onWikimediaAndScribeClick Callback invoked when Wikimedia link is clicked. * @param onShareScribeClick Callback invoked when Share Scribe link is clicked. * @param context Android context to open URLs. - * @param isConjugateApp Flag indicating flavor + * @param isConjugateApp Flag indicating flavor. * * @return A [ScribeItemList] wrapping community external links. */ @@ -245,12 +250,13 @@ object AboutUtil { ): ScribeItemList = remember(isConjugateApp) { ScribeItemList( - items = buildCommunityList( - context, - onShareScribeClick, - onWikimediaAndScribeClick, - isConjugateApp - ), + items = + buildCommunityList( + context, + onShareScribeClick, + onWikimediaAndScribeClick, + isConjugateApp, + ), ) } @@ -261,7 +267,7 @@ object AboutUtil { * @param onMailClick Callback to open email intent. * @param onResetHintsClick Callback to reset onboarding hints. * @param context Android context used to launch external intents. - * @param isConjugateApp Flag indicating flavor + * @param isConjugateApp Flag indicating flavor. * * @return A [ScribeItemList] wrapping feedback and support options. */ From 8fd0d10f2eb1f476191c3d981613172b43f496b2 Mon Sep 17 00:00:00 2001 From: ashb155 Date: Tue, 24 Mar 2026 22:48:07 +0530 Subject: [PATCH 4/4] - added Conjugate flavor tests --- .../be/scri/ui/screens/about/AboutUtilTest.kt | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/app/src/test/kotlin/be/scri/ui/screens/about/AboutUtilTest.kt b/app/src/test/kotlin/be/scri/ui/screens/about/AboutUtilTest.kt index de752c3fc..f5ab1ddc0 100644 --- a/app/src/test/kotlin/be/scri/ui/screens/about/AboutUtilTest.kt +++ b/app/src/test/kotlin/be/scri/ui/screens/about/AboutUtilTest.kt @@ -71,7 +71,6 @@ class AboutUtilTest { assertEquals(5, list.size) - // Checking the resource IDs are preserved, not string values. assertEquals(R.string.i18n_app_about_feedback_rate_scribe, list[0].title) assertEquals(R.string.i18n_app_about_feedback_bug_report, list[1].title) assertEquals(R.string.i18n_app_about_feedback_send_email, list[2].title) @@ -109,13 +108,16 @@ class AboutUtilTest { @Test fun testOnShareScribeClick() { - // Arrange val mockHelper = mockk(relaxed = true) AboutUtil.shareHelper = mockHelper - // Act - AboutUtil.onShareScribeClick(context) - verify { mockHelper.shareScribe(context) } + // Conjugate - true + AboutUtil.onShareScribeClick(context, isConjugateApp = true) + verify { mockHelper.shareScribe(context, true) } + + // Conjugate - false + AboutUtil.onShareScribeClick(context, isConjugateApp = false) + verify { mockHelper.shareScribe(context, false) } } @Test @@ -169,4 +171,54 @@ class AboutUtilTest { verify(exactly = 1) { HintUtils.resetHints(mockContext) } assertTrue(called) } + + @Test + fun `buildCommunityList returns conjugate share string when isConjugateApp is true`() { + val list = + buildCommunityList( + context = context, + onShareScribeClick = {}, + onWikimediaAndScribeClick = {}, + isConjugateApp = true, + ) + assertEquals(R.string.i18n_app_about_community_share_conjugate, list[2].title) + } + + @Test + fun `buildCommunityList returns default share string when isConjugateApp is false`() { + val list = + buildCommunityList( + context = context, + onShareScribeClick = {}, + onWikimediaAndScribeClick = {}, + isConjugateApp = false, + ) + assertEquals(R.string.i18n_app_about_community_share_scribe, list[2].title) + } + + @Test + fun `feedbackAndSupportList returns conjugate rate string when isConjugateApp is true`() { + val list = + feedbackAndSupportList( + context = context, + onRateScribeClick = {}, + onMailClick = {}, + onResetHintsClick = {}, + isConjugateApp = true, + ) + assertEquals(R.string.i18n_app_about_feedback_rate_conjugate, list[0].title) + } + + @Test + fun `feedbackAndSupportList returns default rate string when isConjugateApp is false`() { + val list = + feedbackAndSupportList( + context = context, + onRateScribeClick = {}, + onMailClick = {}, + onResetHintsClick = {}, + isConjugateApp = false, + ) + assertEquals(R.string.i18n_app_about_feedback_rate_scribe, list[0].title) + } }