Skip to content

Commit 0e4ad09

Browse files
committed
refactor (alarm ) : create off alarm button when time out
1 parent 3c68ce2 commit 0e4ad09

4 files changed

Lines changed: 127 additions & 25 deletions

File tree

src/lib/features/note/model/note_model.dart

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:convert';
2+
13
class NoteModel {
24
final String id;
35
final String content;
@@ -10,4 +12,30 @@ class NoteModel {
1012
this.pinned = false,
1113
this.imagePath,
1214
});
13-
}
15+
16+
// --- LOCAL STORAGE HELPERS ---
17+
18+
// Convert Object to Map for local storage
19+
Map<String, dynamic> toMap() {
20+
return {
21+
'id': id,
22+
'content': content,
23+
'pinned': pinned,
24+
'imagePath': imagePath,
25+
};
26+
}
27+
28+
// Create Object from Map
29+
factory NoteModel.fromMap(Map<String, dynamic> map) {
30+
return NoteModel(
31+
id: map['id'],
32+
content: map['content'],
33+
pinned: map['pinned'] ?? false,
34+
imagePath: map['imagePath'],
35+
);
36+
}
37+
38+
// JSON Helpers for SharedPreferences
39+
String toJson() => json.encode(toMap());
40+
factory NoteModel.fromJson(String source) => NoteModel.fromMap(json.decode(source));
41+
}

src/lib/features/note/view/focus_screen.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class FocusScreen extends StatelessWidget {
3030
mainAxisSize: MainAxisSize.min,
3131
crossAxisAlignment: CrossAxisAlignment.start,
3232
children: [
33+
// --- Time Settings ---
3334
Row(
3435
mainAxisAlignment: MainAxisAlignment.spaceBetween,
3536
children: [
@@ -48,6 +49,8 @@ class FocusScreen extends StatelessWidget {
4849
),
4950
Slider(value: currentBreak, min: 1, max: 30, divisions: 29, activeColor: Colors.orange, onChanged: (val) => setStateDialog(() => currentBreak = val)),
5051
const Divider(height: 30),
52+
53+
// --- Hardware Settings ---
5154
SwitchListTile(
5255
title: const Text('Rung', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)),
5356
value: currentVibrate, activeColor: AppColors.primaryBlue, contentPadding: EdgeInsets.zero,
@@ -81,6 +84,7 @@ class FocusScreen extends StatelessWidget {
8184
TextButton(onPressed: () => Navigator.pop(context), child: const Text('Hủy', style: TextStyle(color: Colors.grey))),
8285
ElevatedButton(
8386
onPressed: () {
87+
// Update settings in ViewModel
8488
vm.updateSettings(newPomodoroMinutes: currentPomodoro.toInt(), newBreakMinutes: currentBreak.toInt(), vibrate: currentVibrate, ringtone: currentRingtone);
8589
Navigator.pop(context);
8690
},
@@ -105,6 +109,7 @@ class FocusScreen extends StatelessWidget {
105109
child: Column(
106110
crossAxisAlignment: CrossAxisAlignment.center,
107111
children: [
112+
// --- Header ---
108113
Row(
109114
mainAxisAlignment: MainAxisAlignment.spaceBetween,
110115
children: [
@@ -115,25 +120,28 @@ class FocusScreen extends StatelessWidget {
115120
Text('Tập trung', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF2C3E50))),
116121
],
117122
),
123+
// Settings Icon
118124
GestureDetector(
119125
onTap: () => _showSettingsDialog(context),
120126
child: Container(padding: const EdgeInsets.all(10), decoration: const BoxDecoration(color: Colors.white, shape: BoxShape.circle), child: const Icon(Icons.settings_outlined, color: AppColors.primaryBlue)),
121127
),
122128
],
123129
),
124130
const SizedBox(height: 30),
131+
132+
// --- Main Content Widgets ---
125133
const FocusTabSelector(),
126134
const SizedBox(height: 30),
127135
const TimerDisplayWidget(),
128136
const SizedBox(height: 40),
129137
const TimerControlsWidget(),
130138
const SizedBox(height: 40),
131139
const QuickNoteCard(),
132-
const SizedBox(height: 80),
140+
const SizedBox(height: 80), // Padding for bottom nav bar
133141
],
134142
),
135143
),
136144
),
137145
);
138146
}
139-
}
147+
}

src/lib/features/note/view/focus_widget.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,19 @@ class TimerControlsWidget extends StatelessWidget {
124124
onTap: vm.resetTimer,
125125
),
126126
const SizedBox(width: 30),
127+
128+
// MAIN BUTTON: CHANGES TO RED WHEN RINGING TO STOP ALARM
127129
_buildControlBtn(
128-
icon: vm.isRunning ? Icons.pause_rounded : Icons.play_arrow_rounded,
129-
bgColor: AppColors.primaryBlue,
130+
icon: vm.isRinging
131+
? Icons.notifications_off_rounded // Muted bell icon
132+
: (vm.isRunning ? Icons.pause_rounded : Icons.play_arrow_rounded),
133+
bgColor: vm.isRinging ? Colors.redAccent : AppColors.primaryBlue,
130134
iconColor: Colors.white,
131135
size: 85,
132136
hasShadow: true,
133-
onTap: vm.toggleTimer,
137+
onTap: vm.toggleTimer, // Stops alarm if ringing, otherwise toggles timer
134138
),
139+
135140
const SizedBox(width: 30),
136141
_buildControlBtn(
137142
icon: Icons.skip_next_rounded,
@@ -159,7 +164,7 @@ class TimerControlsWidget extends StatelessWidget {
159164
color: bgColor,
160165
shape: BoxShape.circle,
161166
boxShadow: [
162-
if (hasShadow) BoxShadow(color: AppColors.primaryBlue.withOpacity(0.4), blurRadius: 20, offset: const Offset(0, 10)),
167+
if (hasShadow) BoxShadow(color: bgColor.withOpacity(0.4), blurRadius: 20, offset: const Offset(0, 10)),
163168
if (!hasShadow) BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 5)),
164169
],
165170
),
@@ -222,7 +227,7 @@ class QuickNoteCard extends StatelessWidget {
222227
style: const TextStyle(fontSize: 14, color: Color(0xFF2C3E50)),
223228
),
224229

225-
// SHOW IMAGE PREVIEW IF ANY
230+
// SHOW IMAGE PREVIEW IF SELECTED
226231
if (vm.selectedImagePath != null) ...[
227232
const SizedBox(height: 10),
228233
Stack(
@@ -263,7 +268,7 @@ class QuickNoteCard extends StatelessWidget {
263268
),
264269
ElevatedButton(
265270
onPressed: () {
266-
FocusScope.of(context).unfocus();
271+
FocusScope.of(context).unfocus(); // Dismiss keyboard
267272
context.read<FocusViewModel>().addNote();
268273
},
269274
style: ElevatedButton.styleFrom(
@@ -297,7 +302,7 @@ class QuickNoteCard extends StatelessWidget {
297302
child: Row(
298303
crossAxisAlignment: CrossAxisAlignment.start,
299304
children: [
300-
// CLICK TO REMOVE
305+
// CLICK TO REMOVE BUTTON
301306
GestureDetector(
302307
onTap: () => vm.removeNote(note.id),
303308
child: Container(
@@ -315,7 +320,7 @@ class QuickNoteCard extends StatelessWidget {
315320
if (note.content.isNotEmpty)
316321
Text(note.content, style: const TextStyle(fontSize: 14, color: Color(0xFF2C3E50), height: 1.4)),
317322

318-
// DISPLAY IMAGE IN NOTE
323+
// DISPLAY ATTACHED IMAGE IN NOTE
319324
if (note.imagePath != null) ...[
320325
const SizedBox(height: 8),
321326
ClipRRect(
@@ -353,4 +358,4 @@ class QuickNoteCard extends StatelessWidget {
353358
),
354359
);
355360
}
356-
}
361+
}

0 commit comments

Comments
 (0)