From 118364a2406e685a28d7c2ac790153d5a4b86010 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Fri, 3 Jan 2025 18:03:20 +0530 Subject: [PATCH 01/10] Add thumbnail image basic structure --- .../android/app/classroom/ThumbnailImage.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt new file mode 100644 index 00000000000..11d389d7980 --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -0,0 +1,19 @@ +package org.oppia.android.app.classroom + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp + +@Composable +fun ThumbnailImage(modifier: Modifier = Modifier, imageResId: Int) { + Image( + painter = painterResource(id = imageResId), + contentDescription = null, + modifier = modifier.size(100.dp), + contentScale = ContentScale.Crop + ) +} From fded98f2aa52e63a5a448939f651b5c570f83db9 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Fri, 3 Jan 2025 19:01:26 +0530 Subject: [PATCH 02/10] Convert LessonThumbnailImageView to compose --- .../android/app/classroom/ThumbnailImage.kt | 161 +++++++++++++++++- 1 file changed, 152 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index 11d389d7980..a2c99120895 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -1,19 +1,162 @@ package org.oppia.android.app.classroom import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.size +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp +import org.oppia.android.R +import org.oppia.android.app.model.LessonThumbnail +import org.oppia.android.app.model.LessonThumbnailGraphic +import org.oppia.android.domain.oppialogger.OppiaLogger +import org.oppia.android.util.locale.OppiaLocale +import org.oppia.android.util.parser.image.ImageLoader +import org.oppia.android.util.parser.image.ImageTransformation @Composable -fun ThumbnailImage(modifier: Modifier = Modifier, imageResId: Int) { - Image( - painter = painterResource(id = imageResId), - contentDescription = null, - modifier = modifier.size(100.dp), - contentScale = ContentScale.Crop - ) +fun ThumbnailImage( + modifier: Modifier = Modifier, + entityId: String, + entityType: String, + lessonThumbnail: LessonThumbnail?, + isBlurred: Boolean, + imageLoader: ImageLoader, + resourceBucketName: String, + thumbnailDownloadUrlTemplate: String, + gcsPrefix: String, + oppiaLogger: OppiaLogger, + machineLocale: OppiaLocale.MachineLocale +) { + val context = LocalContext.current + + // Determine the background color and scale type + val backgroundColor = remember(lessonThumbnail) { + lessonThumbnail?.backgroundColorRgb?.toLong()?.let { + (0xff000000L or it).toInt() + } ?: 0xff000000.toInt() + } + val transformations = if (isBlurred) listOf(ImageTransformation.BLUR) else listOf() + + Box( + modifier = modifier + .background(Color(backgroundColor)) + .fillMaxSize() + ) { + if (lessonThumbnail != null) { + val filename = lessonThumbnail.thumbnailFilename + if (filename.isNotEmpty()) { + val imageUrl = remember(filename, entityId, entityType) { + machineLocale.run { + val formattedName = thumbnailDownloadUrlTemplate.formatForMachines( + entityType, + entityId, + filename + ) + "$gcsPrefix/$resourceBucketName/$formattedName" + } + } + + // Load image using ImageLoader + /*ImageLoaderComposable( + imageUrl = imageUrl, + transformations = transformations, + imageLoader = imageLoader, + oppiaLogger = oppiaLogger*//* + )*/ + } else { + // Load drawable resource + val drawableRes = getDrawableResource(lessonThumbnail) + Image( + painter = painterResource(id = drawableRes), + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Fit + ) + } + } + } +} + +/*@Composable +private fun ImageLoaderComposable( + imageUrl: String, + transformations: List, + imageLoader: ImageLoader, + oppiaLogger: OppiaLogger +) { + LaunchedEffect(imageUrl) { + try { + // Use the image loader to fetch the image + imageLoader.loadBitmap(imageUrl, object : ImageViewTa { + override fun onBitmapLoaded(bitmap: Bitmap?) { + // Handle successful image loading + } + + override fun onBitmapFailed(errorDrawable: Drawable?) { + // Handle image loading failure + oppiaLogger.e("LessonThumbnailImage", "Image loading failed") + } + }, transformations) + } catch (e: Exception) { + oppiaLogger.e("LessonThumbnailImage", "Error loading image", e) + } + } +}*/ + +/** Retrieves the drawable resource ID for the lesson thumbnail based on its graphic type. */ +private fun getDrawableResource(lessonThumbnail: LessonThumbnail): Int { + return when (lessonThumbnail.thumbnailGraphic) { + LessonThumbnailGraphic.BAKER -> + R.drawable.lesson_thumbnail_graphic_baker + LessonThumbnailGraphic.CHILD_WITH_BOOK -> + R.drawable.lesson_thumbnail_graphic_child_with_book + LessonThumbnailGraphic.CHILD_WITH_CUPCAKES -> + R.drawable.lesson_thumbnail_graphic_child_with_cupcakes + LessonThumbnailGraphic.CHILD_WITH_FRACTIONS_HOMEWORK -> + R.drawable.lesson_thumbnail_graphic_child_with_fractions_homework + LessonThumbnailGraphic.DUCK_AND_CHICKEN -> + R.drawable.lesson_thumbnail_graphic_duck_and_chicken + LessonThumbnailGraphic.PERSON_WITH_PIE_CHART -> + R.drawable.lesson_thumbnail_graphic_person_with_pie_chart + LessonThumbnailGraphic.IDENTIFYING_THE_PARTS_OF_A_FRACTION -> + R.drawable.topic_fractions_01 + LessonThumbnailGraphic.WRITING_FRACTIONS -> + R.drawable.topic_fractions_02 + LessonThumbnailGraphic.EQUIVALENT_FRACTIONS -> + R.drawable.topic_fractions_03 + LessonThumbnailGraphic.MIXED_NUMBERS_AND_IMPROPER_FRACTIONS -> + R.drawable.topic_fractions_04 + LessonThumbnailGraphic.COMPARING_FRACTIONS -> + R.drawable.topic_fractions_05 + LessonThumbnailGraphic.ADDING_AND_SUBTRACTING_FRACTIONS -> + R.drawable.topic_fractions_06 + LessonThumbnailGraphic.MULTIPLYING_FRACTIONS -> + R.drawable.topic_fractions_07 + LessonThumbnailGraphic.DIVIDING_FRACTIONS -> + R.drawable.topic_fractions_08 + LessonThumbnailGraphic.DERIVE_A_RATIO -> + R.drawable.topic_ratios_01 + LessonThumbnailGraphic.WHAT_IS_A_FRACTION -> + R.drawable.topic_fractions_01 + LessonThumbnailGraphic.FRACTION_OF_A_GROUP -> + R.drawable.topic_fractions_02 + LessonThumbnailGraphic.ADDING_FRACTIONS -> + R.drawable.topic_fractions_03 + LessonThumbnailGraphic.MIXED_NUMBERS -> + R.drawable.topic_fractions_04 + LessonThumbnailGraphic.SCIENCE_CLASSROOM -> + R.drawable.ic_science + LessonThumbnailGraphic.MATHS_CLASSROOM -> + R.drawable.ic_maths + LessonThumbnailGraphic.ENGLISH_CLASSROOM -> + R.drawable.ic_english + else -> + R.drawable.topic_fractions_01 + } } From 04defda4f17b2745f14a1271df515a4c4a126e1d Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 08:46:25 +0530 Subject: [PATCH 03/10] Integrate LessonThumbnailImageView in ThumbnailImage composable (directly inflate xml view) --- .../android/app/classroom/ThumbnailImage.kt | 158 ++---------------- 1 file changed, 12 insertions(+), 146 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index a2c99120895..18be8a22a6b 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -1,162 +1,28 @@ package org.oppia.android.app.classroom -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import org.oppia.android.R +import androidx.compose.ui.viewinterop.AndroidView +import org.oppia.android.app.customview.LessonThumbnailImageView import org.oppia.android.app.model.LessonThumbnail -import org.oppia.android.app.model.LessonThumbnailGraphic -import org.oppia.android.domain.oppialogger.OppiaLogger -import org.oppia.android.util.locale.OppiaLocale -import org.oppia.android.util.parser.image.ImageLoader -import org.oppia.android.util.parser.image.ImageTransformation @Composable fun ThumbnailImage( - modifier: Modifier = Modifier, entityId: String, entityType: String, lessonThumbnail: LessonThumbnail?, - isBlurred: Boolean, - imageLoader: ImageLoader, - resourceBucketName: String, - thumbnailDownloadUrlTemplate: String, - gcsPrefix: String, - oppiaLogger: OppiaLogger, - machineLocale: OppiaLocale.MachineLocale + modifier: Modifier = Modifier, ) { - val context = LocalContext.current - - // Determine the background color and scale type - val backgroundColor = remember(lessonThumbnail) { - lessonThumbnail?.backgroundColorRgb?.toLong()?.let { - (0xff000000L or it).toInt() - } ?: 0xff000000.toInt() - } - val transformations = if (isBlurred) listOf(ImageTransformation.BLUR) else listOf() - - Box( - modifier = modifier - .background(Color(backgroundColor)) - .fillMaxSize() - ) { - if (lessonThumbnail != null) { - val filename = lessonThumbnail.thumbnailFilename - if (filename.isNotEmpty()) { - val imageUrl = remember(filename, entityId, entityType) { - machineLocale.run { - val formattedName = thumbnailDownloadUrlTemplate.formatForMachines( - entityType, - entityId, - filename - ) - "$gcsPrefix/$resourceBucketName/$formattedName" - } - } - - // Load image using ImageLoader - /*ImageLoaderComposable( - imageUrl = imageUrl, - transformations = transformations, - imageLoader = imageLoader, - oppiaLogger = oppiaLogger*//* - )*/ - } else { - // Load drawable resource - val drawableRes = getDrawableResource(lessonThumbnail) - Image( - painter = painterResource(id = drawableRes), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit - ) + AndroidView( + modifier = modifier.fillMaxSize(), + factory = { context -> + // Creates view + LessonThumbnailImageView(context).apply { + setLessonThumbnail(lessonThumbnail) + setEntityId(entityId) + setEntityType(entityType) } } - } -} - -/*@Composable -private fun ImageLoaderComposable( - imageUrl: String, - transformations: List, - imageLoader: ImageLoader, - oppiaLogger: OppiaLogger -) { - LaunchedEffect(imageUrl) { - try { - // Use the image loader to fetch the image - imageLoader.loadBitmap(imageUrl, object : ImageViewTa { - override fun onBitmapLoaded(bitmap: Bitmap?) { - // Handle successful image loading - } - - override fun onBitmapFailed(errorDrawable: Drawable?) { - // Handle image loading failure - oppiaLogger.e("LessonThumbnailImage", "Image loading failed") - } - }, transformations) - } catch (e: Exception) { - oppiaLogger.e("LessonThumbnailImage", "Error loading image", e) - } - } -}*/ - -/** Retrieves the drawable resource ID for the lesson thumbnail based on its graphic type. */ -private fun getDrawableResource(lessonThumbnail: LessonThumbnail): Int { - return when (lessonThumbnail.thumbnailGraphic) { - LessonThumbnailGraphic.BAKER -> - R.drawable.lesson_thumbnail_graphic_baker - LessonThumbnailGraphic.CHILD_WITH_BOOK -> - R.drawable.lesson_thumbnail_graphic_child_with_book - LessonThumbnailGraphic.CHILD_WITH_CUPCAKES -> - R.drawable.lesson_thumbnail_graphic_child_with_cupcakes - LessonThumbnailGraphic.CHILD_WITH_FRACTIONS_HOMEWORK -> - R.drawable.lesson_thumbnail_graphic_child_with_fractions_homework - LessonThumbnailGraphic.DUCK_AND_CHICKEN -> - R.drawable.lesson_thumbnail_graphic_duck_and_chicken - LessonThumbnailGraphic.PERSON_WITH_PIE_CHART -> - R.drawable.lesson_thumbnail_graphic_person_with_pie_chart - LessonThumbnailGraphic.IDENTIFYING_THE_PARTS_OF_A_FRACTION -> - R.drawable.topic_fractions_01 - LessonThumbnailGraphic.WRITING_FRACTIONS -> - R.drawable.topic_fractions_02 - LessonThumbnailGraphic.EQUIVALENT_FRACTIONS -> - R.drawable.topic_fractions_03 - LessonThumbnailGraphic.MIXED_NUMBERS_AND_IMPROPER_FRACTIONS -> - R.drawable.topic_fractions_04 - LessonThumbnailGraphic.COMPARING_FRACTIONS -> - R.drawable.topic_fractions_05 - LessonThumbnailGraphic.ADDING_AND_SUBTRACTING_FRACTIONS -> - R.drawable.topic_fractions_06 - LessonThumbnailGraphic.MULTIPLYING_FRACTIONS -> - R.drawable.topic_fractions_07 - LessonThumbnailGraphic.DIVIDING_FRACTIONS -> - R.drawable.topic_fractions_08 - LessonThumbnailGraphic.DERIVE_A_RATIO -> - R.drawable.topic_ratios_01 - LessonThumbnailGraphic.WHAT_IS_A_FRACTION -> - R.drawable.topic_fractions_01 - LessonThumbnailGraphic.FRACTION_OF_A_GROUP -> - R.drawable.topic_fractions_02 - LessonThumbnailGraphic.ADDING_FRACTIONS -> - R.drawable.topic_fractions_03 - LessonThumbnailGraphic.MIXED_NUMBERS -> - R.drawable.topic_fractions_04 - LessonThumbnailGraphic.SCIENCE_CLASSROOM -> - R.drawable.ic_science - LessonThumbnailGraphic.MATHS_CLASSROOM -> - R.drawable.ic_maths - LessonThumbnailGraphic.ENGLISH_CLASSROOM -> - R.drawable.ic_english - else -> - R.drawable.topic_fractions_01 - } + ) } From ecc62326afa4f02b574a71f4fe3b55a416e3a6e9 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 08:56:58 +0530 Subject: [PATCH 04/10] Use ThumbnailImage in TopicCard --- .../android/app/classroom/ThumbnailImage.kt | 2 +- .../app/classroom/topiclist/TopicCard.kt | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index 18be8a22a6b..546b889a0f4 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -14,10 +14,10 @@ fun ThumbnailImage( lessonThumbnail: LessonThumbnail?, modifier: Modifier = Modifier, ) { + // TODO(#5422): Migrate to jetpack compose. AndroidView( modifier = modifier.fillMaxSize(), factory = { context -> - // Creates view LessonThumbnailImageView(context).apply { setLessonThumbnail(lessonThumbnail) setEntityId(entityId) diff --git a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt index 6e67f6b5e3d..ee2906e6a38 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.sp import org.oppia.android.R +import org.oppia.android.app.classroom.ThumbnailImage import org.oppia.android.app.classroom.getDrawableResource import org.oppia.android.app.home.topiclist.TopicSummaryViewModel @@ -41,7 +42,22 @@ fun TopicCard(topicSummaryViewModel: TopicSummaryViewModel) { Column( verticalArrangement = Arrangement.Center, ) { - Image( + ThumbnailImage( + entityId = topicSummaryViewModel.topicSummary.topicId, + entityType = topicSummaryViewModel.entityType, + lessonThumbnail = topicSummaryViewModel.topicSummary.topicThumbnail, + modifier = Modifier + .aspectRatio(4f / 3f) + .background( + Color( + ( + 0xff000000L or + topicSummaryViewModel.topicSummary.topicThumbnail.backgroundColorRgb.toLong() + ).toInt() + ) + ) + ) + /*Image( painter = painterResource( id = topicSummaryViewModel.topicSummary.topicThumbnail.getDrawableResource() ), @@ -57,7 +73,7 @@ fun TopicCard(topicSummaryViewModel: TopicSummaryViewModel) { ).toInt() ) ) - ) + )*/ TopicCardTextSection(topicSummaryViewModel) } } From cd3d7f64e17bedc06a605bd6bf3036d57911b5b6 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 09:29:02 +0530 Subject: [PATCH 05/10] Use ThumbnailImage in all remaining cards --- .../app/classroom/ClassroomListViewModel.kt | 3 +++ .../android/app/classroom/ThumbnailImage.kt | 2 +- .../classroom/classroomlist/ClassroomList.kt | 16 +++++---------- .../promotedlist/ComingSoonTopicList.kt | 14 +++++-------- .../promotedlist/PromotedStoryList.kt | 13 +++++------- .../app/classroom/topiclist/TopicCard.kt | 20 ------------------- .../ClassroomSummaryViewModel.kt | 1 + .../html/ExplorationHtmlParserEntityType.kt | 4 ++++ .../parser/html/HtmlParserEntityTypeModule.kt | 6 ++++++ 9 files changed, 30 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ClassroomListViewModel.kt b/app/src/main/java/org/oppia/android/app/classroom/ClassroomListViewModel.kt index 985ed3816c9..a382b5efce2 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ClassroomListViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ClassroomListViewModel.kt @@ -40,6 +40,7 @@ import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders.Companion.combineWith import org.oppia.android.util.data.DataProviders.Companion.toLiveData +import org.oppia.android.util.parser.html.ClassroomHtmlParserEntityType import org.oppia.android.util.parser.html.StoryHtmlParserEntityType import org.oppia.android.util.parser.html.TopicHtmlParserEntityType @@ -57,6 +58,7 @@ class ClassroomListViewModel( private val profileManagementController: ProfileManagementController, private val topicListController: TopicListController, private val classroomController: ClassroomController, + @ClassroomHtmlParserEntityType private val classroomEntityType: String, @TopicHtmlParserEntityType private val topicEntityType: String, @StoryHtmlParserEntityType private val storyEntityType: String, private val resourceHandler: AppLanguageResourceHandler, @@ -270,6 +272,7 @@ class ClassroomListViewModel( ClassroomSummaryViewModel( fragment as ClassroomSummaryClickListener, ephemeralClassroomSummary, + classroomEntityType, translationController ) } diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index 546b889a0f4..87aebbe6d1c 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -14,7 +14,7 @@ fun ThumbnailImage( lessonThumbnail: LessonThumbnail?, modifier: Modifier = Modifier, ) { - // TODO(#5422): Migrate to jetpack compose. + // TODO(#5422): Migrate to Jetpack Compose once the Glide Compose library becomes compatible. AndroidView( modifier = modifier.fillMaxSize(), factory = { context -> diff --git a/app/src/main/java/org/oppia/android/app/classroom/classroomlist/ClassroomList.kt b/app/src/main/java/org/oppia/android/app/classroom/classroomlist/ClassroomList.kt index 5a5db784fec..be1182d7dcc 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/classroomlist/ClassroomList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/classroomlist/ClassroomList.kt @@ -2,7 +2,6 @@ package org.oppia.android.app.classroom.classroomlist import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -23,14 +22,13 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.integerResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.oppia.android.R -import org.oppia.android.app.classroom.getDrawableResource +import org.oppia.android.app.classroom.ThumbnailImage import org.oppia.android.app.home.classroomlist.ClassroomSummaryViewModel /** Test tag for the classroom list. */ @@ -103,14 +101,10 @@ fun ClassroomCard( horizontalAlignment = Alignment.CenterHorizontally, ) { AnimatedVisibility(visible = !isSticky) { - Image( - painter = painterResource( - id = classroomSummaryViewModel - .classroomSummary - .classroomThumbnail - .getDrawableResource() - ), - contentDescription = classroomSummaryViewModel.title, + ThumbnailImage( + entityId = classroomSummaryViewModel.classroomSummary.classroomId, + entityType = classroomSummaryViewModel.entityType, + lessonThumbnail = classroomSummaryViewModel.classroomSummary.classroomThumbnail, modifier = Modifier .testTag("${CLASSROOM_CARD_ICON_TEST_TAG}_${classroomSummaryViewModel.title}") .padding(bottom = dimensionResource(id = R.dimen.classrooms_card_icon_padding_bottom)) diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt index 0d9de4ef7b0..f9ccaa2515c 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt @@ -1,6 +1,5 @@ package org.oppia.android.app.classroom.promotedlist -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -22,7 +21,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight @@ -31,7 +29,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.oppia.android.R -import org.oppia.android.app.classroom.getDrawableResource +import org.oppia.android.app.classroom.ThumbnailImage import org.oppia.android.app.home.promotedlist.ComingSoonTopicListViewModel import org.oppia.android.app.home.promotedlist.ComingSoonTopicsViewModel import org.oppia.android.util.locale.OppiaLocale @@ -104,12 +102,10 @@ fun ComingSoonTopicCard( Column( verticalArrangement = Arrangement.Center, ) { - Image( - painter = painterResource( - id = comingSoonTopicsViewModel.topicSummary.lessonThumbnail.getDrawableResource() - ), - contentDescription = "Picture of a " + - "${comingSoonTopicsViewModel.topicSummary.lessonThumbnail.thumbnailGraphic.name}.", + ThumbnailImage( + entityId = comingSoonTopicsViewModel.topicSummary.topicId, + entityType = comingSoonTopicsViewModel.entityType, + lessonThumbnail = comingSoonTopicsViewModel.topicSummary.lessonThumbnail, modifier = Modifier .aspectRatio(4f / 3f) .background( diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt index ba9fcc32e13..53455e2b986 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt @@ -2,7 +2,6 @@ package org.oppia.android.app.classroom.promotedlist import android.view.View import android.view.ViewGroup -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable @@ -27,7 +26,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight @@ -36,7 +34,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.oppia.android.R -import org.oppia.android.app.classroom.getDrawableResource +import org.oppia.android.app.classroom.ThumbnailImage import org.oppia.android.app.home.promotedlist.PromotedStoryListViewModel import org.oppia.android.app.home.promotedlist.PromotedStoryViewModel import org.oppia.android.util.locale.OppiaLocale @@ -141,11 +139,10 @@ fun PromotedStoryCard( Column( modifier = cardColumnModifier ) { - Image( - painter = painterResource( - id = promotedStoryViewModel.promotedStory.lessonThumbnail.getDrawableResource() - ), - contentDescription = promotedStoryViewModel.storyTitle, + ThumbnailImage( + entityId = promotedStoryViewModel.promotedStory.storyId, + entityType = promotedStoryViewModel.entityType, + lessonThumbnail = promotedStoryViewModel.promotedStory.lessonThumbnail, modifier = Modifier .aspectRatio(16f / 9f) .background( diff --git a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt index ee2906e6a38..35fe4c4342c 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt @@ -1,6 +1,5 @@ package org.oppia.android.app.classroom.topiclist -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -15,7 +14,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight @@ -24,7 +22,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.sp import org.oppia.android.R import org.oppia.android.app.classroom.ThumbnailImage -import org.oppia.android.app.classroom.getDrawableResource import org.oppia.android.app.home.topiclist.TopicSummaryViewModel /** Displays a card with the topic summary information. */ @@ -57,23 +54,6 @@ fun TopicCard(topicSummaryViewModel: TopicSummaryViewModel) { ) ) ) - /*Image( - painter = painterResource( - id = topicSummaryViewModel.topicSummary.topicThumbnail.getDrawableResource() - ), - contentDescription = "Picture of a " + - "${topicSummaryViewModel.topicSummary.topicThumbnail.thumbnailGraphic.name}.", - modifier = Modifier - .aspectRatio(4f / 3f) - .background( - Color( - ( - 0xff000000L or - topicSummaryViewModel.topicSummary.topicThumbnail.backgroundColorRgb.toLong() - ).toInt() - ) - ) - )*/ TopicCardTextSection(topicSummaryViewModel) } } diff --git a/app/src/main/java/org/oppia/android/app/home/classroomlist/ClassroomSummaryViewModel.kt b/app/src/main/java/org/oppia/android/app/home/classroomlist/ClassroomSummaryViewModel.kt index 3ffb03b1b80..95d7f3c0b5b 100644 --- a/app/src/main/java/org/oppia/android/app/home/classroomlist/ClassroomSummaryViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/home/classroomlist/ClassroomSummaryViewModel.kt @@ -10,6 +10,7 @@ import java.util.Objects class ClassroomSummaryViewModel( private val classroomSummaryClickListener: ClassroomSummaryClickListener, ephemeralClassroomSummary: EphemeralClassroomSummary, + val entityType: String, translationController: TranslationController, ) : HomeItemViewModel() { /** The [ClassroomSummary] retrieved from the [EphemeralClassroomSummary]. */ diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ExplorationHtmlParserEntityType.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ExplorationHtmlParserEntityType.kt index 876b90d4503..9bd022ffa14 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ExplorationHtmlParserEntityType.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ExplorationHtmlParserEntityType.kt @@ -10,6 +10,10 @@ annotation class ExplorationHtmlParserEntityType @Qualifier annotation class ConceptCardHtmlParserEntityType +/** Qualifier for injecting the entity type for classroom card. */ +@Qualifier +annotation class ClassroomHtmlParserEntityType + /** Qualifier for injecting the entity type for review card. */ @Qualifier annotation class TopicHtmlParserEntityType diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/HtmlParserEntityTypeModule.kt b/utility/src/main/java/org/oppia/android/util/parser/html/HtmlParserEntityTypeModule.kt index 9f479a379be..42763e35749 100755 --- a/utility/src/main/java/org/oppia/android/util/parser/html/HtmlParserEntityTypeModule.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/HtmlParserEntityTypeModule.kt @@ -18,6 +18,12 @@ class HtmlParserEntityTypeModule { return "skill" } + @Provides + @ClassroomHtmlParserEntityType + fun provideClassroomCardHtmlParserEntityType(): String { + return "classroom" + } + @Provides @TopicHtmlParserEntityType fun provideReviewCardHtmlParserEntityType(): String { From 59b2c25ce23cc4029f99d6fdf38ee983ddd09dc3 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 09:47:40 +0530 Subject: [PATCH 06/10] Add missing parameter --- .../android/app/classroom/ClassroomListFragmentPresenter.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ClassroomListFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/classroom/ClassroomListFragmentPresenter.kt index 069d3012187..fe3d0de4f62 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ClassroomListFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ClassroomListFragmentPresenter.kt @@ -66,6 +66,7 @@ import org.oppia.android.domain.translation.TranslationController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import org.oppia.android.util.locale.OppiaLocale +import org.oppia.android.util.parser.html.ClassroomHtmlParserEntityType import org.oppia.android.util.parser.html.StoryHtmlParserEntityType import org.oppia.android.util.parser.html.TopicHtmlParserEntityType import org.oppia.android.util.platformparameter.EnableOnboardingFlowV2 @@ -84,6 +85,7 @@ class ClassroomListFragmentPresenter @Inject constructor( private val topicListController: TopicListController, private val classroomController: ClassroomController, private val oppiaLogger: OppiaLogger, + @ClassroomHtmlParserEntityType private val classroomEntityType: String, @TopicHtmlParserEntityType private val topicEntityType: String, @StoryHtmlParserEntityType private val storyEntityType: String, private val resourceHandler: AppLanguageResourceHandler, @@ -120,6 +122,7 @@ class ClassroomListFragmentPresenter @Inject constructor( profileManagementController, topicListController, classroomController, + classroomEntityType, topicEntityType, storyEntityType, resourceHandler, From 0d0767aad915303fe7c46dc285fce68171c7f7d1 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 09:51:57 +0530 Subject: [PATCH 07/10] Add classroom thumbnail drawables to LessonThumbnailImageView --- .../android/app/customview/LessonThumbnailImageView.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt b/app/src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt index f843b940a26..254b680437c 100644 --- a/app/src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt +++ b/app/src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt @@ -193,6 +193,12 @@ class LessonThumbnailImageView @JvmOverloads constructor( R.drawable.topic_fractions_03 LessonThumbnailGraphic.MIXED_NUMBERS -> R.drawable.topic_fractions_04 + LessonThumbnailGraphic.SCIENCE_CLASSROOM -> + R.drawable.ic_science + LessonThumbnailGraphic.MATHS_CLASSROOM -> + R.drawable.ic_maths + LessonThumbnailGraphic.ENGLISH_CLASSROOM -> + R.drawable.ic_english else -> R.drawable.topic_fractions_01 } From 45d6ff49c9e455b3bf6cf336d4b9e926ad074d11 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 11:03:38 +0530 Subject: [PATCH 08/10] Fix recomposition of ThumbnailImage and remove extra background colour --- .../oppia/android/app/classroom/ThumbnailImage.kt | 5 +++++ .../classroom/promotedlist/ComingSoonTopicList.kt | 12 +----------- .../app/classroom/promotedlist/PromotedStoryList.kt | 11 +---------- .../android/app/classroom/topiclist/TopicCard.kt | 11 +---------- 4 files changed, 8 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index 87aebbe6d1c..4b43be1c0cd 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -23,6 +23,11 @@ fun ThumbnailImage( setEntityId(entityId) setEntityType(entityType) } + }, + update = { view -> + view.setLessonThumbnail(lessonThumbnail) + view.setEntityId(entityId) + view.setEntityType(entityType) } ) } diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt index f9ccaa2515c..9d83703368d 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt @@ -106,17 +106,7 @@ fun ComingSoonTopicCard( entityId = comingSoonTopicsViewModel.topicSummary.topicId, entityType = comingSoonTopicsViewModel.entityType, lessonThumbnail = comingSoonTopicsViewModel.topicSummary.lessonThumbnail, - modifier = Modifier - .aspectRatio(4f / 3f) - .background( - Color( - ( - 0xff000000L or - comingSoonTopicsViewModel - .topicSummary.lessonThumbnail.backgroundColorRgb.toLong() - ).toInt() - ) - ) + modifier = Modifier.aspectRatio(4f / 3f) ) ComingSoonTopicCardTextSection(comingSoonTopicsViewModel) } diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt index 53455e2b986..aab463bf1c3 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt @@ -143,16 +143,7 @@ fun PromotedStoryCard( entityId = promotedStoryViewModel.promotedStory.storyId, entityType = promotedStoryViewModel.entityType, lessonThumbnail = promotedStoryViewModel.promotedStory.lessonThumbnail, - modifier = Modifier - .aspectRatio(16f / 9f) - .background( - Color( - ( - 0xff000000L or - promotedStoryViewModel.promotedStory.lessonThumbnail.backgroundColorRgb.toLong() - ).toInt() - ) - ) + modifier = Modifier.aspectRatio(16f / 9f) ) Text( text = promotedStoryViewModel.nextChapterTitle, diff --git a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt index 35fe4c4342c..dc77b65a761 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt @@ -43,16 +43,7 @@ fun TopicCard(topicSummaryViewModel: TopicSummaryViewModel) { entityId = topicSummaryViewModel.topicSummary.topicId, entityType = topicSummaryViewModel.entityType, lessonThumbnail = topicSummaryViewModel.topicSummary.topicThumbnail, - modifier = Modifier - .aspectRatio(4f / 3f) - .background( - Color( - ( - 0xff000000L or - topicSummaryViewModel.topicSummary.topicThumbnail.backgroundColorRgb.toLong() - ).toInt() - ) - ) + modifier = Modifier.aspectRatio(4f / 3f) ) TopicCardTextSection(topicSummaryViewModel) } From 100f35a5922f450bf295c2d33077ce24ffd8c0fc Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 11:43:29 +0530 Subject: [PATCH 09/10] Remove unused imports --- .../android/app/classroom/promotedlist/ComingSoonTopicList.kt | 1 - .../android/app/classroom/promotedlist/PromotedStoryList.kt | 2 -- .../java/org/oppia/android/app/classroom/topiclist/TopicCard.kt | 1 - 3 files changed, 4 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt index 9d83703368d..cdd42b37da8 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/ComingSoonTopicList.kt @@ -17,7 +17,6 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource diff --git a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt index aab463bf1c3..b668febb073 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt @@ -2,7 +2,6 @@ package org.oppia.android.app.classroom.promotedlist import android.view.View import android.view.ViewGroup -import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -22,7 +21,6 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource diff --git a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt index dc77b65a761..8707851f5bf 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/topiclist/TopicCard.kt @@ -11,7 +11,6 @@ import androidx.compose.material.Card import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.text.font.FontFamily From 772890dd68ae80960802aba2c28cba02e44d59e4 Mon Sep 17 00:00:00 2001 From: Saptak Manna Date: Mon, 6 Jan 2025 12:27:43 +0530 Subject: [PATCH 10/10] Fix static checks --- .../oppia/android/app/classroom/ThumbnailImage.kt | 13 +++++++++++++ scripts/assets/test_file_exemptions.textproto | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt index 4b43be1c0cd..035d86598d7 100644 --- a/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt +++ b/app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt @@ -7,6 +7,19 @@ import androidx.compose.ui.viewinterop.AndroidView import org.oppia.android.app.customview.LessonThumbnailImageView import org.oppia.android.app.model.LessonThumbnail +/** + * A composable function that displays a lesson thumbnail image using a custom Android view. + * + * This function integrates the [LessonThumbnailImageView] within a Compose layout, allowing it + * to render a lesson thumbnail image based on the provided parameters. The implementation + * currently relies on a traditional Android View approach due to compatibility issues with the + * Glide Compose library. + * + * @param entityId The unique identifier for the entity associated with the thumbnail. + * @param entityType The type of the entity (e.g., classroom, topic, story). + * @param lessonThumbnail The [LessonThumbnail] containing metadata required to load the image. + * @param modifier The [Modifier] to be applied to the layout, defaulting to [Modifier]. + */ @Composable fun ThumbnailImage( entityId: String, diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index c358c7d68a4..0baccac8151 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -298,6 +298,10 @@ test_file_exemption { exempted_file_path: "app/src/main/java/org/oppia/android/app/classroom/promotedlist/PromotedStoryList.kt" test_file_not_required: true } +test_file_exemption { + exempted_file_path: "app/src/main/java/org/oppia/android/app/classroom/ThumbnailImage.kt" + test_file_not_required: true +} test_file_exemption { exempted_file_path: "app/src/main/java/org/oppia/android/app/classroom/topiclist/AllTopicsHeaderText.kt" test_file_not_required: true