Skip to content

Commit 2edc80a

Browse files
committed
Add text input
1 parent 23a03a3 commit 2edc80a

File tree

6 files changed

+42
-36
lines changed

6 files changed

+42
-36
lines changed

android/app/src/main/kotlin/com/example/flutter_alarm_manager_poc/activity/AlarmActivity.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package com.example.flutter_alarm_manager_poc.activity
22

33
import android.os.Bundle
4-
import android.widget.Toast
54
import androidx.activity.ComponentActivity
65
import androidx.activity.compose.setContent
76
import androidx.compose.material3.MaterialTheme
87
import androidx.compose.material3.Surface
98
import com.example.flutter_alarm_manager_poc.alarmNotificationService.AlarmNotificationService
109
import com.example.flutter_alarm_manager_poc.alarmNotificationService.AlarmNotificationServiceImpl
11-
import com.example.flutter_alarm_manager_poc.alarmScheduler.AlarmScheduler
12-
import com.example.flutter_alarm_manager_poc.alarmScheduler.AlarmSchedulerImpl
13-
import com.example.flutter_alarm_manager_poc.model.AlarmItem
1410
import com.example.flutter_alarm_manager_poc.screens.AlarmScreen
1511
import io.flutter.embedding.engine.FlutterEngine
1612
import io.flutter.embedding.engine.FlutterEngineCache
@@ -24,15 +20,13 @@ class AlarmActivity : ComponentActivity() {
2420
private var flutterEngine: FlutterEngine? = null
2521
private var isNewEngineCreated = false // create new engine when app is closed and use existing when app is resumed state
2622
private lateinit var alarmNotificationService: AlarmNotificationService
27-
private lateinit var alarmScheduler: AlarmScheduler
2823

2924
override fun onCreate(savedInstanceState: Bundle?) {
3025
super.onCreate(savedInstanceState)
3126
actionBar?.hide()
3227

3328
val alarmId = intent.getIntExtra("ALARM_ID", -1)
3429

35-
3630
alarmNotificationService = AlarmNotificationServiceImpl(this)
3731

3832
// Check if a cached engine is available
@@ -58,8 +52,12 @@ class AlarmActivity : ComponentActivity() {
5852
MaterialTheme {
5953
Surface(color = MaterialTheme.colorScheme.onSurface) {
6054
AlarmScreen(
61-
onAccept = { q1, q2 ->
62-
val answerData = mapOf("feeling" to q1, "sleepQuality" to q2)
55+
onAccept = { q1, q2, additionalText ->
56+
val answerData = mapOf(
57+
"feeling" to q1,
58+
"sleepQuality" to q2,
59+
"additionalInfo" to additionalText
60+
)
6361
val payload = mapOf("status" to "answered", "data" to answerData)
6462
channel.invokeMethod("questionnaireFinished", payload)
6563
alarmNotificationService.cancelNotification(alarmId)

android/app/src/main/kotlin/com/example/flutter_alarm_manager_poc/screens/AlarmScreen.kt

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package com.example.flutter_alarm_manager_poc.screens
22

3-
import androidx.compose.animation.core.FastOutSlowInEasing
4-
import androidx.compose.animation.core.RepeatMode
5-
import androidx.compose.animation.core.animateDpAsState
6-
import androidx.compose.animation.core.infiniteRepeatable
7-
import androidx.compose.animation.core.repeatable
8-
import androidx.compose.animation.core.tween
93
import androidx.compose.foundation.background
104
import androidx.compose.foundation.clickable
115
import androidx.compose.foundation.layout.Arrangement
@@ -14,23 +8,20 @@ import androidx.compose.foundation.layout.Column
148
import androidx.compose.foundation.layout.Row
159
import androidx.compose.foundation.layout.fillMaxSize
1610
import androidx.compose.foundation.layout.fillMaxWidth
17-
import androidx.compose.foundation.layout.height
1811
import androidx.compose.foundation.layout.padding
1912
import androidx.compose.foundation.layout.size
20-
import androidx.compose.foundation.layout.width
2113
import androidx.compose.foundation.shape.CircleShape
22-
import androidx.compose.foundation.shape.RoundedCornerShape
2314
import androidx.compose.material.icons.Icons
24-
import androidx.compose.material.icons.filled.Check
2515
import androidx.compose.material.icons.filled.Close
2616
import androidx.compose.material.icons.filled.Snooze
27-
import androidx.compose.material3.Button
2817
import androidx.compose.material3.Icon
2918
import androidx.compose.material3.MaterialTheme
19+
import androidx.compose.material3.OutlinedTextField
3020
import androidx.compose.material3.RadioButton
3121
import androidx.compose.material3.RadioButtonDefaults
3222
import androidx.compose.material3.Surface
3323
import androidx.compose.material3.Text
24+
import androidx.compose.material3.TextFieldDefaults
3425
import androidx.compose.runtime.Composable
3526
import androidx.compose.runtime.LaunchedEffect
3627
import androidx.compose.runtime.getValue
@@ -39,38 +30,34 @@ import androidx.compose.runtime.remember
3930
import androidx.compose.runtime.setValue
4031
import androidx.compose.ui.Alignment
4132
import androidx.compose.ui.Modifier
42-
import androidx.compose.ui.draw.clip
43-
import androidx.compose.ui.draw.shadow
4433
import androidx.compose.ui.graphics.Color
4534
import androidx.compose.ui.graphics.vector.ImageVector
46-
import androidx.compose.ui.layout.ContentScale
4735
import androidx.compose.ui.text.TextStyle
4836
import androidx.compose.ui.text.font.FontStyle
4937
import androidx.compose.ui.tooling.preview.Preview
5038
import androidx.compose.ui.unit.dp
51-
import coil.compose.AsyncImage
5239
import com.example.flutter_alarm_manager_poc.utils.convertMillisToDate
5340
import com.example.flutter_alarm_manager_poc.utils.convertMillisToTime
54-
import org.w3c.dom.Text
5541

5642
@Composable
5743
fun AlarmScreen(
58-
onAccept: (Int, Int) -> Unit,
44+
onAccept: (Int, Int, String) -> Unit,
5945
onDecline: () -> Unit,
6046
onSnooze: () -> Unit
6147
) {
6248
var question1Selection by remember { mutableStateOf<Int?>(null) }
6349
var question2Selection by remember { mutableStateOf<Int?>(null) }
50+
var additionalText by remember { mutableStateOf("") }
6451

65-
// Exit condition 1: Answering all questions automatically triggers the accept action.
52+
// Reinstated Exit Condition 1: Answering all questions automatically triggers the accept action.
6653
LaunchedEffect(question1Selection, question2Selection) {
6754
// Storing in local variables for stability within the coroutine scope
6855
val q1 = question1Selection
6956
val q2 = question2Selection
7057

71-
// If both questions have been answered, trigger the accept action.
58+
// If both questions have been answered, trigger the accept action, including any text.
7259
if (q1 != null && q2 != null) {
73-
onAccept(q1, q2)
60+
onAccept(q1, q2, additionalText)
7461
}
7562
}
7663

@@ -113,6 +100,26 @@ fun AlarmScreen(
113100
selectedOption = question2Selection,
114101
onOptionSelected = { question2Selection = it }
115102
)
103+
OutlinedTextField(
104+
value = additionalText,
105+
onValueChange = { additionalText = it },
106+
label = { Text("Additional information (optional)") },
107+
modifier = Modifier
108+
.fillMaxWidth()
109+
.padding(top = 8.dp),
110+
colors = TextFieldDefaults.colors(
111+
focusedTextColor = Color.White,
112+
unfocusedTextColor = Color.White,
113+
cursorColor = Color.White,
114+
focusedContainerColor = Color.Transparent,
115+
unfocusedContainerColor = Color.Transparent,
116+
focusedIndicatorColor = Color.White,
117+
unfocusedIndicatorColor = Color.Gray,
118+
focusedLabelColor = Color.White,
119+
unfocusedLabelColor = Color.Gray,
120+
),
121+
maxLines = 3
122+
)
116123
}
117124

118125
Row(
@@ -156,12 +163,11 @@ fun ButtonAction(
156163
Icon(
157164
imageVector = icon,
158165
contentDescription = text,
159-
tint = Color(0xFF8A2BE2), // This makes the icon white
166+
tint = Color(0xFF8A2BE2),
160167
modifier = Modifier
161168
.size(40.dp)
162-
.align(Alignment.Center) // Adjust the size of the icon as needed
169+
.align(Alignment.Center)
163170
)
164-
165171
}
166172
Text(
167173
modifier = Modifier.padding(top = 8.dp),

lib/hive/models/alarm_action.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ class AlarmAction {
1313
final int timestamp;
1414

1515
@HiveField(2)
16-
final Map<String, int>? answers;
16+
final Map<String, dynamic>? answers;
1717
}

lib/hive/models/alarm_action.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/hive/service/database_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class DatabaseService {
3535

3636
// Add an alarm action to the Hive box
3737
Future<void> storeAlarmAction(AlarmActionType actionType,
38-
{Map<String, int>? answers}) async {
38+
{Map<String, dynamic>? answers}) async {
3939
try {
4040
await _alarmBox.add(
4141
AlarmAction(

lib/utils/alarm_method_channel.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ class AlarmMethodChannel {
5656
if (status != null) {
5757
// 1. Store the user's action (side-effect).
5858
final answerData = args['data'] as Map<dynamic, dynamic>?;
59-
final answers = answerData
60-
?.map((key, value) => MapEntry(key.toString(), value as int));
59+
60+
// [FIX] Remove the cast 'as int'. This now correctly creates a Map<String, dynamic>
61+
final answers =
62+
answerData?.map((key, value) => MapEntry(key.toString(), value));
6163

6264
final AlarmActionType actionType;
6365
final QuestionnaireResult result;

0 commit comments

Comments
 (0)