@@ -46,72 +46,28 @@ import java.util.Locale
4646/* *
4747 * Card component that displays the result of a completed rover mission.
4848 * Shows final position, success status, and timestamp with expandable original input.
49+ *
50+ * @param missionResult The mission result data to display
51+ * @param modifier Optional modifier for styling
4952 */
50- @Suppress(" CyclomaticComplexMethod" )
5153@Composable
5254fun MissionResultCard (
5355 missionResult : MissionResult ,
5456 modifier : Modifier = Modifier ,
5557) {
5658 val dateFormatter = SimpleDateFormat (" MMM dd, yyyy HH:mm" , Locale .getDefault())
5759 val formattedDate = dateFormatter.format(Date (missionResult.timestamp))
58- var isInputExpanded by remember { mutableStateOf(false ) }
5960
6061 MarsCard (
6162 title = stringResource(R .string.mission_result),
6263 modifier = modifier,
6364 contentDescription = stringResource(R .string.cd_mission_card)
6465 ) {
65- // Status row with icon
66- Row (
67- verticalAlignment = Alignment .CenterVertically ,
68- modifier = Modifier .fillMaxWidth()
69- ) {
70- Icon (
71- imageVector =
72- if (missionResult.isSuccess) {
73- Icons .Default .CheckCircle
74- } else {
75- Icons .Default .Warning
76- },
77- contentDescription =
78- if (missionResult.isSuccess) {
79- stringResource(R .string.cd_mission_success)
80- } else {
81- stringResource(R .string.cd_mission_failed)
82- },
83- tint =
84- if (missionResult.isSuccess) {
85- MaterialTheme .colorScheme.primary
86- } else {
87- MaterialTheme .colorScheme.error
88- },
89- modifier = Modifier .size(24 .dp)
90- )
91-
92- Spacer (modifier = Modifier .width(8 .dp))
93-
94- Text (
95- text =
96- if (missionResult.isSuccess) {
97- stringResource(R .string.mission_completed_successfully)
98- } else {
99- stringResource(R .string.mission_failed)
100- },
101- style = MaterialTheme .typography.titleMedium,
102- fontWeight = FontWeight .SemiBold ,
103- color =
104- if (missionResult.isSuccess) {
105- MaterialTheme .colorScheme.primary
106- } else {
107- MaterialTheme .colorScheme.error
108- }
109- )
110- }
66+ MissionStatusRow (isSuccess = missionResult.isSuccess)
11167
11268 Spacer (modifier = Modifier .height(6 .dp))
11369
114- // Final position
70+ // Final position and mission details
11571 Column (
11672 verticalArrangement = Arrangement .spacedBy(8 .dp)
11773 ) {
@@ -124,60 +80,7 @@ fun MissionResultCard(
12480 // Show original input if available
12581 missionResult.originalInput?.let { input ->
12682 Spacer (modifier = Modifier .height(8 .dp))
127-
128- // Input label with expand/collapse button
129- Row (
130- modifier = Modifier .fillMaxWidth(),
131- horizontalArrangement = Arrangement .SpaceBetween ,
132- verticalAlignment = Alignment .CenterVertically
133- ) {
134- Text (
135- text = stringResource(R .string.mission_instructions),
136- style = MaterialTheme .typography.bodyMedium,
137- fontWeight = FontWeight .Medium ,
138- color = MaterialTheme .colorScheme.onSurface
139- )
140-
141- if (input.length > Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
142- IconButton (
143- onClick = { isInputExpanded = ! isInputExpanded },
144- modifier = Modifier .size(24 .dp)
145- ) {
146- Icon (
147- imageVector = if (isInputExpanded) Icons .Default .KeyboardArrowUp else Icons .Default .KeyboardArrowDown ,
148- contentDescription =
149- if (isInputExpanded) {
150- stringResource(
151- R .string.cd_collapse_input
152- )
153- } else {
154- stringResource(R .string.cd_expand_input)
155- },
156- tint = MaterialTheme .colorScheme.primary
157- )
158- }
159- }
160- }
161-
162- // Input text - expandable
163- Text (
164- text =
165- if (isInputExpanded || input.length <= Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
166- input
167- } else {
168- input.take(Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) + " ..."
169- },
170- style = MaterialTheme .typography.bodySmall,
171- color = MaterialTheme .colorScheme.onSurfaceVariant,
172- maxLines = if (isInputExpanded) Int .MAX_VALUE else 2 ,
173- overflow = if (isInputExpanded) TextOverflow .Visible else TextOverflow .Ellipsis ,
174- modifier =
175- if (input.length > Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
176- Modifier .clickable { isInputExpanded = ! isInputExpanded }
177- } else {
178- Modifier
179- }
180- )
83+ ExpandableInputSection (input = input)
18184 }
18285
18386 // Completed timestamp - right aligned, placed after mission instructions
@@ -193,6 +96,133 @@ fun MissionResultCard(
19396 }
19497}
19598
99+ /* *
100+ * Displays the mission status (success/failure) with appropriate icon and text.
101+ *
102+ * @param isSuccess Whether the mission was successful
103+ * @param modifier Optional modifier for styling
104+ */
105+ @Composable
106+ private fun MissionStatusRow (
107+ isSuccess : Boolean ,
108+ modifier : Modifier = Modifier ,
109+ ) {
110+ Row (
111+ verticalAlignment = Alignment .CenterVertically ,
112+ modifier = modifier.fillMaxWidth()
113+ ) {
114+ Icon (
115+ imageVector =
116+ if (isSuccess) {
117+ Icons .Default .CheckCircle
118+ } else {
119+ Icons .Default .Warning
120+ },
121+ contentDescription =
122+ if (isSuccess) {
123+ stringResource(R .string.cd_mission_success)
124+ } else {
125+ stringResource(R .string.cd_mission_failed)
126+ },
127+ tint =
128+ if (isSuccess) {
129+ MaterialTheme .colorScheme.primary
130+ } else {
131+ MaterialTheme .colorScheme.error
132+ },
133+ modifier = Modifier .size(24 .dp)
134+ )
135+
136+ Spacer (modifier = Modifier .width(8 .dp))
137+
138+ Text (
139+ text =
140+ if (isSuccess) {
141+ stringResource(R .string.mission_completed_successfully)
142+ } else {
143+ stringResource(R .string.mission_failed)
144+ },
145+ style = MaterialTheme .typography.titleMedium,
146+ fontWeight = FontWeight .SemiBold ,
147+ color =
148+ if (isSuccess) {
149+ MaterialTheme .colorScheme.primary
150+ } else {
151+ MaterialTheme .colorScheme.error
152+ }
153+ )
154+ }
155+ }
156+
157+ /* *
158+ * Displays mission input instructions with expand/collapse functionality for long inputs.
159+ *
160+ * @param input The input string to display
161+ * @param modifier Optional modifier for styling
162+ */
163+ @Composable
164+ private fun ExpandableInputSection (
165+ input : String ,
166+ modifier : Modifier = Modifier ,
167+ ) {
168+ var isInputExpanded by remember { mutableStateOf(false ) }
169+
170+ Column (modifier = modifier) {
171+ // Input label with expand/collapse button
172+ Row (
173+ modifier = Modifier .fillMaxWidth(),
174+ horizontalArrangement = Arrangement .SpaceBetween ,
175+ verticalAlignment = Alignment .CenterVertically
176+ ) {
177+ Text (
178+ text = stringResource(R .string.mission_instructions),
179+ style = MaterialTheme .typography.bodyMedium,
180+ fontWeight = FontWeight .Medium ,
181+ color = MaterialTheme .colorScheme.onSurface
182+ )
183+
184+ // Show expand/collapse button only for long inputs
185+ if (input.length > Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
186+ IconButton (
187+ onClick = { isInputExpanded = ! isInputExpanded },
188+ modifier = Modifier .size(24 .dp)
189+ ) {
190+ Icon (
191+ imageVector = if (isInputExpanded) Icons .Default .KeyboardArrowUp else Icons .Default .KeyboardArrowDown ,
192+ contentDescription =
193+ if (isInputExpanded) {
194+ stringResource(R .string.cd_collapse_input)
195+ } else {
196+ stringResource(R .string.cd_expand_input)
197+ },
198+ tint = MaterialTheme .colorScheme.primary
199+ )
200+ }
201+ }
202+ }
203+
204+ // Input text - expandable for long content
205+ Text (
206+ text =
207+ if (isInputExpanded || input.length <= Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
208+ input
209+ } else {
210+ input.take(Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) + " ..."
211+ },
212+ style = MaterialTheme .typography.bodySmall,
213+ color = MaterialTheme .colorScheme.onSurfaceVariant,
214+ maxLines = if (isInputExpanded) Int .MAX_VALUE else 2 ,
215+ overflow = if (isInputExpanded) TextOverflow .Visible else TextOverflow .Ellipsis ,
216+ modifier =
217+ if (input.length > Constants .UI .MAX_INPUT_PREVIEW_LENGTH ) {
218+ Modifier .clickable { isInputExpanded = ! isInputExpanded }
219+ } else {
220+ Modifier
221+ }
222+ )
223+ }
224+ }
225+
196226@Preview(name = " Mission Result Card - Success" , showBackground = true )
197227@Composable
198228private fun MissionResultCardSuccessPreview () {
0 commit comments