mirror of
				https://github.com/AdrianKuta/KahootQuiz.git
				synced 2025-10-31 00:43:40 +01:00 
			
		
		
		
	feat: Expand domain models and implement full DTO to domain mapping
This commit significantly expands the domain models to fully represent the quiz structure and implements the complete mapping logic in `QuizMapper` to convert `QuizResponseDto` and its nested DTOs to their corresponding domain models.
Key changes:
- **Domain Layer (`domain` module):**
    - Introduced a `QuizId` value class for type safety.
    - Added comprehensive domain models for all aspects of a quiz, including:
        - `Quiz`: Updated to include all fields from the DTO.
        - `Question`, `Choice`, `Video`, `ImageMetadata`, `MediaItem`, `ChoiceRange`: For question details.
        - `CoverMetadata`, `ExtractedColor`, `Crop`, `Point`: For cover image information.
        - `ContentTags`: For curriculum and generated codes.
        - `Metadata`, `Access`, `FeaturedListMembership`, `LastEdit`, `VersionMetadata`: For quiz metadata.
        - `LanguageInfo`, `Channel`: Common reusable models.
    - Organized domain models into separate files for better maintainability (e.g., `Question.kt`, `CoverMetadata.kt`).
    - Added a placeholder `QuestionModels.kt` to indicate that models were moved.
- **Data Layer (`model:data` module):**
    - Implemented a complete `toDomainModel()` extension function in `QuizMapper.kt` to map all fields from `QuizResponseDto` and its nested DTOs (like `CoverMetadataDto`, `QuestionDto`, etc.) to the new domain models.
    - This includes mapping for lists and nullable fields.
- **App Module (`app` module):**
    - Updated `MainActivity` to access `quizId.value` due to `QuizId` being a value class.
- **Network Layer (`core:network` module):**
    - Changed `QuizResponseDto.uuid` to be non-nullable (`String`) as it's essential for mapping to `QuizId`.
    - Removed `QuizResponse.kt` as DTOs were previously split into individual files.
			
			
This commit is contained in:
		
							
								
								
									
										4
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								.idea/deploymentTargetSelector.xml
									
									
									
										generated
									
									
									
								
							| @@ -4,10 +4,10 @@ | |||||||
|     <selectionStates> |     <selectionStates> | ||||||
|       <SelectionState runConfigName="app"> |       <SelectionState runConfigName="app"> | ||||||
|         <option name="selectionMode" value="DROPDOWN" /> |         <option name="selectionMode" value="DROPDOWN" /> | ||||||
|         <DropdownSelection timestamp="2025-09-01T13:50:36.976965Z"> |         <DropdownSelection timestamp="2025-09-02T20:25:37.879520Z"> | ||||||
|           <Target type="DEFAULT_BOOT"> |           <Target type="DEFAULT_BOOT"> | ||||||
|             <handle> |             <handle> | ||||||
|               <DeviceId pluginId="LocalEmulator" identifier="path=/Users/adriankuta/.android/avd/Pixel_8_Pro.avd" /> |               <DeviceId pluginId="LocalEmulator" identifier="path=/Users/adriankuta/.android/avd/Pixel_9_Pro.avd" /> | ||||||
|             </handle> |             </handle> | ||||||
|           </Target> |           </Target> | ||||||
|         </DropdownSelection> |         </DropdownSelection> | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|  |   <component name="GradleMigrationSettings" migrationVersion="1" /> | ||||||
|   <component name="GradleSettings"> |   <component name="GradleSettings"> | ||||||
|     <option name="linkedExternalProjectsSettings"> |     <option name="linkedExternalProjectsSettings"> | ||||||
|       <GradleProjectSettings> |       <GradleProjectSettings> | ||||||
| @@ -24,6 +25,13 @@ | |||||||
|             <option value="$PROJECT_DIR$/app" /> |             <option value="$PROJECT_DIR$/app" /> | ||||||
|             <option value="$PROJECT_DIR$/build-logic" /> |             <option value="$PROJECT_DIR$/build-logic" /> | ||||||
|             <option value="$PROJECT_DIR$/build-logic/convention" /> |             <option value="$PROJECT_DIR$/build-logic/convention" /> | ||||||
|  |             <option value="$PROJECT_DIR$/core" /> | ||||||
|  |             <option value="$PROJECT_DIR$/core/network" /> | ||||||
|  |             <option value="$PROJECT_DIR$/domain" /> | ||||||
|  |             <option value="$PROJECT_DIR$/model" /> | ||||||
|  |             <option value="$PROJECT_DIR$/model/data" /> | ||||||
|  |             <option value="$PROJECT_DIR$/ui" /> | ||||||
|  |             <option value="$PROJECT_DIR$/ui/quiz" /> | ||||||
|           </set> |           </set> | ||||||
|         </option> |         </option> | ||||||
|       </GradleProjectSettings> |       </GradleProjectSettings> | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ class MainActivity : ComponentActivity() { | |||||||
|                     var quizId by remember { mutableStateOf<String?>(null) } |                     var quizId by remember { mutableStateOf<String?>(null) } | ||||||
|  |  | ||||||
|                     LaunchedEffect(Unit) { |                     LaunchedEffect(Unit) { | ||||||
|                         quizId = getQuizUseCase().id |                         quizId = getQuizUseCase().id.value | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     Greeting( |                     Greeting( | ||||||
|   | |||||||
| @@ -1,10 +0,0 @@ | |||||||
| package dev.adriankuta.kahootquiz.core.network.models |  | ||||||
|  |  | ||||||
| // This file used to contain all DTOs in one place. |  | ||||||
| // The DTOs have been split into separate files for maintainability: |  | ||||||
| // - QuizResponseDto.kt |  | ||||||
| // - CommonDtos.kt |  | ||||||
| // - CoverDtos.kt |  | ||||||
| // - QuestionDtos.kt |  | ||||||
| // - MetadataDtos.kt |  | ||||||
| // Keeping this file as a placeholder to avoid breaking any imports by file path (package remains the same). |  | ||||||
| @@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName | |||||||
|  |  | ||||||
| // Root response for a Kahoot quiz details (network layer DTO) | // Root response for a Kahoot quiz details (network layer DTO) | ||||||
| data class QuizResponseDto( | data class QuizResponseDto( | ||||||
|     val uuid: String?, |     val uuid: String, | ||||||
|     val language: String?, |     val language: String?, | ||||||
|     val creator: String?, |     val creator: String?, | ||||||
|     @SerializedName("creator_username") val creatorUsername: String?, |     @SerializedName("creator_username") val creatorUsername: String?, | ||||||
|   | |||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Access settings | ||||||
|  |  | ||||||
|  | data class Access( | ||||||
|  |     val groupRead: List<String>?, | ||||||
|  |     val folderGroupIds: List<String>?, | ||||||
|  |     val features: List<String>? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Minimal channel info | ||||||
|  |  | ||||||
|  | data class Channel(val id: String?) | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | data class Choice( | ||||||
|  |     val answer: String?, | ||||||
|  |     val correct: Boolean?, | ||||||
|  |     val languageInfo: LanguageInfo? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Slider range for "slider" question type | ||||||
|  |  | ||||||
|  | data class ChoiceRange( | ||||||
|  |     val start: Int?, | ||||||
|  |     val end: Int?, | ||||||
|  |     val step: Int?, | ||||||
|  |     val correct: Int?, | ||||||
|  |     val tolerance: Int? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Content tags domain model | ||||||
|  |  | ||||||
|  | data class ContentTags( | ||||||
|  |     val curriculumCodes: List<String>?, | ||||||
|  |     val generatedCurriculumCodes: List<String>? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Cover metadata and related domain models | ||||||
|  |  | ||||||
|  | data class CoverMetadata( | ||||||
|  |     val id: String?, | ||||||
|  |     val altText: String?, | ||||||
|  |     val contentType: String?, | ||||||
|  |     val origin: String?, | ||||||
|  |     val externalRef: String?, | ||||||
|  |     val resources: String?, | ||||||
|  |     val width: Int?, | ||||||
|  |     val height: Int?, | ||||||
|  |     val extractedColors: List<ExtractedColor>?, | ||||||
|  |     val blurhash: String?, | ||||||
|  |     val crop: Crop? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Crop descriptor | ||||||
|  |  | ||||||
|  | data class Crop( | ||||||
|  |     val origin: Point?, | ||||||
|  |     val target: Point?, | ||||||
|  |     val circular: Boolean? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Color extracted from cover image | ||||||
|  |  | ||||||
|  | data class ExtractedColor( | ||||||
|  |     val swatch: String?, | ||||||
|  |     val rgbHex: String? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Featured list membership | ||||||
|  |  | ||||||
|  | data class FeaturedListMembership( | ||||||
|  |     val list: String?, | ||||||
|  |     val addedAt: Long? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Image metadata appearing in multiple places | ||||||
|  |  | ||||||
|  | data class ImageMetadata( | ||||||
|  |     val id: String?, | ||||||
|  |     val altText: String? = null, | ||||||
|  |     val contentType: String?, | ||||||
|  |     val origin: String? = null, | ||||||
|  |     val externalRef: String? = null, | ||||||
|  |     val resources: String? = null, | ||||||
|  |     val width: Int? = null, | ||||||
|  |     val height: Int? = null, | ||||||
|  |     val effects: List<String>? = null, | ||||||
|  |     val crop: Crop? = null | ||||||
|  | ) | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Common simple models reused across the domain layer | ||||||
|  |  | ||||||
|  | data class LanguageInfo( | ||||||
|  |     val language: String?, | ||||||
|  |     val lastUpdatedOn: Long?, | ||||||
|  |     val readAloudSupported: Boolean? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Last edit information | ||||||
|  |  | ||||||
|  | data class LastEdit( | ||||||
|  |     val editorUserId: String?, | ||||||
|  |     val editorUsername: String?, | ||||||
|  |     val editTimestamp: Long? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Generic media item on question | ||||||
|  |  | ||||||
|  | data class MediaItem( | ||||||
|  |     val type: String?, | ||||||
|  |     val zIndex: Int?, | ||||||
|  |     val isColorOnly: Boolean?, | ||||||
|  |     val id: String?, | ||||||
|  |     val altText: String? = null, | ||||||
|  |     val contentType: String?, | ||||||
|  |     val origin: String? = null, | ||||||
|  |     val externalRef: String? = null, | ||||||
|  |     val resources: String? = null, | ||||||
|  |     val width: Int? = null, | ||||||
|  |     val height: Int? = null, | ||||||
|  |     val crop: Crop? = null | ||||||
|  | ) | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Metadata section domain models | ||||||
|  |  | ||||||
|  | data class Metadata( | ||||||
|  |     val access: Access?, | ||||||
|  |     val duplicationProtection: Boolean?, | ||||||
|  |     val featuredListMemberships: List<FeaturedListMembership>?, | ||||||
|  |     val lastEdit: LastEdit?, | ||||||
|  |     val versionMetadata: VersionMetadata? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Geometry helpers | ||||||
|  |  | ||||||
|  | data class Point( | ||||||
|  |     val x: Int?, | ||||||
|  |     val y: Int? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | import kotlin.time.Duration | ||||||
|  |  | ||||||
|  | // Question and choice related domain models | ||||||
|  |  | ||||||
|  | data class Question( | ||||||
|  |     val type: String?, | ||||||
|  |     val question: String?, | ||||||
|  |     val time: Duration?, | ||||||
|  |     val points: Boolean?, | ||||||
|  |     val pointsMultiplier: Int?, | ||||||
|  |     val choices: List<Choice>?, | ||||||
|  |     val layout: String?, | ||||||
|  |     val image: String?, | ||||||
|  |     val imageMetadata: ImageMetadata?, | ||||||
|  |     val resources: String?, | ||||||
|  |     val video: Video?, | ||||||
|  |     val questionFormat: Int?, | ||||||
|  |     val languageInfo: LanguageInfo?, | ||||||
|  |     val media: List<MediaItem>?, | ||||||
|  |     val choiceRange: ChoiceRange? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Moved: data classes have been split into separate files. | ||||||
| @@ -1,5 +1,35 @@ | |||||||
| package dev.adriankuta.kahootquiz.domain.models | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Domain model representing a Quiz and its nested data | ||||||
|  |  | ||||||
| data class Quiz( | data class Quiz( | ||||||
|     val id: String |     val id: QuizId, | ||||||
|  |     val language: String?, | ||||||
|  |     val creator: String?, | ||||||
|  |     val creatorUsername: String?, | ||||||
|  |     val compatibilityLevel: Int?, | ||||||
|  |     val creatorPrimaryUsage: String?, | ||||||
|  |     val folderId: String?, | ||||||
|  |     val themeId: String?, | ||||||
|  |     val visibility: Int?, | ||||||
|  |     val audience: String?, | ||||||
|  |     val title: String?, | ||||||
|  |     val description: String?, | ||||||
|  |     val quizType: String?, | ||||||
|  |     val cover: String?, | ||||||
|  |     val coverMetadata: CoverMetadata?, | ||||||
|  |     val questions: List<Question>, | ||||||
|  |     val contentTags: ContentTags?, | ||||||
|  |     val metadata: Metadata?, | ||||||
|  |     val resources: String?, | ||||||
|  |     val slug: String?, | ||||||
|  |     val languageInfo: LanguageInfo?, | ||||||
|  |     val inventoryItemIds: List<String>, | ||||||
|  |     val channels: List<Channel>, | ||||||
|  |     val isValid: Boolean?, | ||||||
|  |     val playAsGuest: Boolean?, | ||||||
|  |     val hasRestrictedContent: Boolean?, | ||||||
|  |     val type: String?, | ||||||
|  |     val created: Long?, | ||||||
|  |     val modified: Long? | ||||||
| ) | ) | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | data class QuizId( | ||||||
|  |     val value: String, | ||||||
|  | ) | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | // Version metadata | ||||||
|  |  | ||||||
|  | data class VersionMetadata( | ||||||
|  |     val version: Int?, | ||||||
|  |     val created: Long?, | ||||||
|  |     val creator: String? | ||||||
|  | ) | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package dev.adriankuta.kahootquiz.domain.models | ||||||
|  |  | ||||||
|  | data class Video( | ||||||
|  |     val id: String? = null, | ||||||
|  |     val startTime: Int?, | ||||||
|  |     val endTime: Int?, | ||||||
|  |     val service: String?, | ||||||
|  |     val fullUrl: String? | ||||||
|  | ) | ||||||
| @@ -1,7 +1,176 @@ | |||||||
| package dev.adriankuta.kahootquiz.model.data.mappers | package dev.adriankuta.kahootquiz.model.data.mappers | ||||||
|  |  | ||||||
| import dev.adriankuta.kahootquiz.core.network.models.QuizResponseDto | import dev.adriankuta.kahootquiz.core.network.models.* | ||||||
| import dev.adriankuta.kahootquiz.domain.models.Quiz | import dev.adriankuta.kahootquiz.domain.models.* | ||||||
|  |  | ||||||
| internal fun QuizResponseDto.toDomainModel(): Quiz = | internal fun QuizResponseDto.toDomainModel(): Quiz = | ||||||
|     Quiz(this.uuid ?: "") |     Quiz( | ||||||
|  |         id = QuizId(uuid), | ||||||
|  |         language = language, | ||||||
|  |         creator = creator, | ||||||
|  |         creatorUsername = creatorUsername, | ||||||
|  |         compatibilityLevel = compatibilityLevel, | ||||||
|  |         creatorPrimaryUsage = creatorPrimaryUsage, | ||||||
|  |         folderId = folderId, | ||||||
|  |         themeId = themeId, | ||||||
|  |         visibility = visibility, | ||||||
|  |         audience = audience, | ||||||
|  |         title = title, | ||||||
|  |         description = description, | ||||||
|  |         quizType = quizType, | ||||||
|  |         cover = cover, | ||||||
|  |         coverMetadata = coverMetadata?.toDomain(), | ||||||
|  |         questions = questions?.map { it.toDomain() } ?: emptyList(), | ||||||
|  |         contentTags = contentTags?.toDomain(), | ||||||
|  |         metadata = metadata?.toDomain(), | ||||||
|  |         resources = resources, | ||||||
|  |         slug = slug, | ||||||
|  |         languageInfo = languageInfo?.toDomain(), | ||||||
|  |         inventoryItemIds = inventoryItemIds ?: emptyList(), | ||||||
|  |         channels = channels?.map { it.toDomain() } ?: emptyList(), | ||||||
|  |         isValid = isValid, | ||||||
|  |         playAsGuest = playAsGuest, | ||||||
|  |         hasRestrictedContent = hasRestrictedContent, | ||||||
|  |         type = type, | ||||||
|  |         created = created, | ||||||
|  |         modified = modified | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  | private fun CoverMetadataDto.toDomain(): CoverMetadata = CoverMetadata( | ||||||
|  |     id = id, | ||||||
|  |     altText = altText, | ||||||
|  |     contentType = contentType, | ||||||
|  |     origin = origin, | ||||||
|  |     externalRef = externalRef, | ||||||
|  |     resources = resources, | ||||||
|  |     width = width, | ||||||
|  |     height = height, | ||||||
|  |     extractedColors = extractedColors?.map { it.toDomain() }, | ||||||
|  |     blurhash = blurhash, | ||||||
|  |     crop = crop?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun ExtractedColorDto.toDomain(): ExtractedColor = ExtractedColor( | ||||||
|  |     swatch = swatch, | ||||||
|  |     rgbHex = rgbHex | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun CropDto.toDomain(): Crop = Crop( | ||||||
|  |     origin = origin?.toDomain(), | ||||||
|  |     target = target?.toDomain(), | ||||||
|  |     circular = circular | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun PointDto.toDomain(): Point = Point(x = x, y = y) | ||||||
|  |  | ||||||
|  | private fun ContentTagsDto.toDomain(): ContentTags = ContentTags( | ||||||
|  |     curriculumCodes = curriculumCodes, | ||||||
|  |     generatedCurriculumCodes = generatedCurriculumCodes | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun MetadataDto.toDomain(): Metadata = Metadata( | ||||||
|  |     access = access?.toDomain(), | ||||||
|  |     duplicationProtection = duplicationProtection, | ||||||
|  |     featuredListMemberships = featuredListMemberships?.map { it.toDomain() }, | ||||||
|  |     lastEdit = lastEdit?.toDomain(), | ||||||
|  |     versionMetadata = versionMetadata?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun AccessDto.toDomain(): Access = Access( | ||||||
|  |     groupRead = groupRead, | ||||||
|  |     folderGroupIds = folderGroupIds, | ||||||
|  |     features = features | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun FeaturedListMembershipDto.toDomain(): FeaturedListMembership = FeaturedListMembership( | ||||||
|  |     list = list, | ||||||
|  |     addedAt = addedAt | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun LastEditDto.toDomain(): LastEdit = LastEdit( | ||||||
|  |     editorUserId = editorUserId, | ||||||
|  |     editorUsername = editorUsername, | ||||||
|  |     editTimestamp = editTimestamp | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun VersionMetadataDto.toDomain(): VersionMetadata = VersionMetadata( | ||||||
|  |     version = version, | ||||||
|  |     created = created, | ||||||
|  |     creator = creator | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun LanguageInfoDto.toDomain(): LanguageInfo = LanguageInfo( | ||||||
|  |     language = language, | ||||||
|  |     lastUpdatedOn = lastUpdatedOn, | ||||||
|  |     readAloudSupported = readAloudSupported | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun ChannelDto.toDomain(): Channel = Channel(id = id) | ||||||
|  |  | ||||||
|  | private fun QuestionDto.toDomain(): Question = Question( | ||||||
|  |     type = type, | ||||||
|  |     question = question, | ||||||
|  |     time = time, | ||||||
|  |     points = points, | ||||||
|  |     pointsMultiplier = pointsMultiplier, | ||||||
|  |     choices = choices?.map { it.toDomain() }, | ||||||
|  |     layout = layout, | ||||||
|  |     image = image, | ||||||
|  |     imageMetadata = imageMetadata?.toDomain(), | ||||||
|  |     resources = resources, | ||||||
|  |     video = video?.toDomain(), | ||||||
|  |     questionFormat = questionFormat, | ||||||
|  |     languageInfo = languageInfo?.toDomain(), | ||||||
|  |     media = media?.map { it.toDomain() }, | ||||||
|  |     choiceRange = choiceRange?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun ChoiceDto.toDomain(): Choice = Choice( | ||||||
|  |     answer = answer, | ||||||
|  |     correct = correct, | ||||||
|  |     languageInfo = languageInfo?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun VideoDto.toDomain(): Video = Video( | ||||||
|  |     id = id, | ||||||
|  |     startTime = startTime, | ||||||
|  |     endTime = endTime, | ||||||
|  |     service = service, | ||||||
|  |     fullUrl = fullUrl | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun ImageMetadataDto.toDomain(): ImageMetadata = ImageMetadata( | ||||||
|  |     id = id, | ||||||
|  |     altText = altText, | ||||||
|  |     contentType = contentType, | ||||||
|  |     origin = origin, | ||||||
|  |     externalRef = externalRef, | ||||||
|  |     resources = resources, | ||||||
|  |     width = width, | ||||||
|  |     height = height, | ||||||
|  |     effects = effects, | ||||||
|  |     crop = crop?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun MediaItemDto.toDomain(): MediaItem = MediaItem( | ||||||
|  |     type = type, | ||||||
|  |     zIndex = zIndex, | ||||||
|  |     isColorOnly = isColorOnly, | ||||||
|  |     id = id, | ||||||
|  |     altText = altText, | ||||||
|  |     contentType = contentType, | ||||||
|  |     origin = origin, | ||||||
|  |     externalRef = externalRef, | ||||||
|  |     resources = resources, | ||||||
|  |     width = width, | ||||||
|  |     height = height, | ||||||
|  |     crop = crop?.toDomain() | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | private fun ChoiceRangeDto.toDomain(): ChoiceRange = ChoiceRange( | ||||||
|  |     start = start, | ||||||
|  |     end = end, | ||||||
|  |     step = step, | ||||||
|  |     correct = correct, | ||||||
|  |     tolerance = tolerance | ||||||
|  | ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	![github-actions[bot]@users.noreply.github.com](/assets/img/avatar_default.png) GitHub Actions Bot
					GitHub Actions Bot