From fe6859717b39195e4d0cf96b8e9a70de04ff8d6f Mon Sep 17 00:00:00 2001 From: Ben Henning Date: Fri, 17 May 2024 02:03:16 +0000 Subject: [PATCH] Initial changes to support classrooms. This doesn't actually finish the new data definitions or properly integrate them, nor is it updating any local development assets. --- domain/BUILD.bazel | 4 +- domain/domain_assets.bzl | 10 ++--- .../domain/topic/TopicListController.kt | 42 +++++++++---------- model/src/main/proto/topic.proto | 36 ++++++++++++++-- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel index ebc2daa97ab..14a3af45dea 100755 --- a/domain/BUILD.bazel +++ b/domain/BUILD.bazel @@ -97,8 +97,8 @@ DOMAIN_ASSETS = generate_assets_list_from_text_protos( "GJ2rLXRKD5hw", "omzF4oqgeTXd", ], - topic_list_file_names = [ - "topics", + classroom_list_file_names = [ + "classrooms", ], ) diff --git a/domain/domain_assets.bzl b/domain/domain_assets.bzl index 89a3ae008a3..39d7ea486c8 100644 --- a/domain/domain_assets.bzl +++ b/domain/domain_assets.bzl @@ -6,7 +6,7 @@ load("//model:text_proto_assets.bzl", "generate_proto_binary_assets") def generate_assets_list_from_text_protos( name, - topic_list_file_names, + classroom_list_file_names, topic_file_names, subtopic_file_names, story_file_names, @@ -17,7 +17,7 @@ def generate_assets_list_from_text_protos( Args: name: str. The name of this generation instance. This will be a prefix for derived targets. - topic_list_file_names: list of str. The list of topic list file names. + classroom_list_file_names: list of str. The classroom list file names. topic_file_names: list of str. The list of topic file names. subtopic_file_names: list of str. The list of subtopic file names. story_file_names: list of str. The list of story file names. @@ -29,10 +29,10 @@ def generate_assets_list_from_text_protos( """ return generate_proto_binary_assets( name = name, - names = topic_list_file_names, + names = classroom_list_file_names, proto_dep_name = "topic", - proto_type_name = "TopicIdList", - name_prefix = "topic_id_list", + proto_type_name = "ClassroomList", + name_prefix = "classroom_list", asset_dir = "src/main/assets", proto_dep_bazel_target_prefix = "//model/src/main/proto", proto_package = "model", diff --git a/domain/src/main/java/org/oppia/android/domain/topic/TopicListController.kt b/domain/src/main/java/org/oppia/android/domain/topic/TopicListController.kt index fee2a02022d..5fc6564e7d8 100644 --- a/domain/src/main/java/org/oppia/android/domain/topic/TopicListController.kt +++ b/domain/src/main/java/org/oppia/android/domain/topic/TopicListController.kt @@ -5,6 +5,7 @@ import org.json.JSONObject import org.oppia.android.app.model.ChapterPlayState import org.oppia.android.app.model.ChapterProgress import org.oppia.android.app.model.ChapterSummary +import org.oppia.android.app.model.ClassroomList import org.oppia.android.app.model.ComingSoonTopicList import org.oppia.android.app.model.EphemeralTopicSummary import org.oppia.android.app.model.LessonThumbnail @@ -18,7 +19,6 @@ import org.oppia.android.app.model.StoryRecord import org.oppia.android.app.model.StorySummary import org.oppia.android.app.model.SubtitledHtml import org.oppia.android.app.model.Topic -import org.oppia.android.app.model.TopicIdList import org.oppia.android.app.model.TopicList import org.oppia.android.app.model.TopicPlayAvailability import org.oppia.android.app.model.TopicPlayAvailability.AvailabilityCase.AVAILABLE_TO_PLAY_IN_FUTURE @@ -44,8 +44,6 @@ import javax.inject.Singleton private const val ONE_WEEK_IN_DAYS = 7 private const val TOPIC_BG_COLOR = "#C6DCDA" -private const val BAKER_BG_COLOR = "#0F63A3" -private const val DUCK_BG_COLOR = "#05538F" private const val CHAPTER_BG_COLOR_1 = "#F8BF74" private const val CHAPTER_BG_COLOR_2 = "#D68F78" @@ -135,16 +133,16 @@ class TopicListController @Inject constructor( private fun createTopicList(contentLocale: OppiaLocale.ContentLocale): TopicList { return if (loadLessonProtosFromAssets) { - val topicIdList = + val classroomList = assetRepository.loadProtoFromLocalAssets( - assetName = "topics", - baseMessage = TopicIdList.getDefaultInstance() + assetName = "classrooms", + baseMessage = ClassroomList.getDefaultInstance() ) return TopicList.newBuilder().apply { // Only include topics currently playable in the topic list. addAllTopicSummary( - topicIdList.topicIdsList.map { - createEphemeralTopicSummary(it, contentLocale) + classroomList.classroomsList.flatMap { classroom -> + classroom.topicIdsList.map { createEphemeralTopicSummary(it, contentLocale) } }.filter { it.topicSummary.topicPlayAvailability.availabilityCase == AVAILABLE_TO_PLAY_NOW } @@ -577,14 +575,12 @@ class TopicListController @Inject constructor( contentLocale: OppiaLocale.ContentLocale ): List { return if (loadLessonProtosFromAssets) { - val topicIdList = + val topicIdsList = assetRepository.loadProtoFromLocalAssets( - assetName = "topics", - baseMessage = TopicIdList.getDefaultInstance() - ) - return computeSuggestedStoriesForTopicIds( - topicProgressList, topicIdList.topicIdsList, contentLocale - ) + assetName = "classrooms", + baseMessage = ClassroomList.getDefaultInstance() + ).flatMap { it.topicIdsList } + return computeSuggestedStoriesForTopicIds(topicProgressList, topicIdsList, contentLocale) } else computeSuggestedStoriesFromJson(topicProgressList, contentLocale) } @@ -877,7 +873,7 @@ internal fun createTopicThumbnail0(): LessonThumbnail { internal fun createTopicThumbnail1(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.DUCK_AND_CHICKEN) - .setBackgroundColorRgb(Color.parseColor(DUCK_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(TOPIC_BG_COLOR)) .build() } @@ -891,7 +887,7 @@ internal fun createTopicThumbnail2(): LessonThumbnail { internal fun createTopicThumbnail3(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.BAKER) - .setBackgroundColorRgb(Color.parseColor(BAKER_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(TOPIC_BG_COLOR)) .build() } @@ -905,7 +901,7 @@ internal fun createDefaultStoryThumbnail(): LessonThumbnail { internal fun createStoryThumbnail0(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.DUCK_AND_CHICKEN) - .setBackgroundColorRgb(0x0F63A3) + .setBackgroundColorRgb(0xa5d3ec) .build() } @@ -926,7 +922,7 @@ internal fun createStoryThumbnail2(): LessonThumbnail { internal fun createStoryThumbnail3(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.BAKER) - .setBackgroundColorRgb(0x0F63A3) + .setBackgroundColorRgb(0xa5a2d3) .build() } @@ -947,7 +943,7 @@ internal fun createChapterThumbnail0(): LessonThumbnail { internal fun createChapterThumbnail1(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.DUCK_AND_CHICKEN) - .setBackgroundColorRgb(Color.parseColor(DUCK_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(CHAPTER_BG_COLOR_2)) .build() } @@ -968,21 +964,21 @@ internal fun createChapterThumbnail3(): LessonThumbnail { internal fun createChapterThumbnail4(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.BAKER) - .setBackgroundColorRgb(Color.parseColor(BAKER_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(CHAPTER_BG_COLOR_1)) .build() } internal fun createChapterThumbnail5(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.DUCK_AND_CHICKEN) - .setBackgroundColorRgb(Color.parseColor(DUCK_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(CHAPTER_BG_COLOR_2)) .build() } internal fun createChapterThumbnail8(): LessonThumbnail { return LessonThumbnail.newBuilder() .setThumbnailGraphic(LessonThumbnailGraphic.DUCK_AND_CHICKEN) - .setBackgroundColorRgb(Color.parseColor(DUCK_BG_COLOR)) + .setBackgroundColorRgb(Color.parseColor(CHAPTER_BG_COLOR_1)) .build() } diff --git a/model/src/main/proto/topic.proto b/model/src/main/proto/topic.proto index b71bdda02dc..004980d147a 100755 --- a/model/src/main/proto/topic.proto +++ b/model/src/main/proto/topic.proto @@ -547,10 +547,38 @@ message EphemeralRevisionCard { WrittenTranslationContext written_translation_context = 2; } -// Corresponds to a local file cataloging all topics available to load. -message TopicIdList { - // The list of IDs corresponding to topics available on the local filesystem. - repeated string topic_ids = 1; +// Corresponds to a local file cataloging all available classrooms in the app. +message ClassroomList { + // The list of classrooms available to the app. + repeated ClassroomRecord classrooms = 1; +} + +// Corresponds to a loadable classroom. +message ClassroomRecord { + // The classroom's ID. + string id = 1; + + // Mapping from content_id to a TranslationMapping for each SubtitledHtml in this classroom that + // has a corresponding translation. + map written_translations = 2; + + // The title of the classroom. + SubtitledHtml translatable_title = 3; + + // The thumbnail corresponding to this classroom. + LessonThumbnail classroom_thumbnail = 4; + + // A map from topic ID to a TopicIdList indicating the prerequisite topics to suggest to the user + // before they play the topic given by the key. Note that the keys of this map indicate the + // complete list of topics contained within this classroom. The prerequisite list of topics may + // include topics outside of this classroom. + map topic_prerequisites = 5; + + // Represents a list of topic IDs (to be used in the context of topic deps in a classroom). + message TopicIdList { + // A list of topics IDs. + repeated string topic_ids = 1; + } } // Corresponds to a local file cataloging all concept cards available to load.