Skip to content

Commit a199c2e

Browse files
committed
Add bonus feature: swipe to lock recording
1 parent 92f0b4f commit a199c2e

File tree

1 file changed

+69
-8
lines changed

1 file changed

+69
-8
lines changed

lib/src/widgets/record_button.dart

+69-8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class _RecordButtonState extends State<RecordButton> {
3434
Timer? timer;
3535
String recordDuration = "00:00";
3636
late Record record;
37+
bool isLocked = false;
3738

3839
@override
3940
void initState() {
@@ -75,6 +76,7 @@ class _RecordButtonState extends State<RecordButton> {
7576
@override
7677
void dispose() {
7778
record.dispose();
79+
timer?.cancel();
7880
super.dispose();
7981
}
8082

@@ -84,8 +86,9 @@ class _RecordButtonState extends State<RecordButton> {
8486
clipBehavior: Clip.none,
8587
children: [
8688
lockSlider(),
87-
timerSlider(context),
89+
cancelSlider(),
8890
audioButton(),
91+
if (isLocked) timerLocked(),
8992
],
9093
);
9194
}
@@ -122,7 +125,7 @@ class _RecordButtonState extends State<RecordButton> {
122125
);
123126
}
124127

125-
Widget timerSlider(BuildContext context) {
128+
Widget cancelSlider() {
126129
return Positioned(
127130
right: -timerAnimation.value,
128131
child: Container(
@@ -152,6 +155,58 @@ class _RecordButtonState extends State<RecordButton> {
152155
);
153156
}
154157

158+
Widget timerLocked() {
159+
return Positioned(
160+
right: 0,
161+
child: Container(
162+
height: size,
163+
width: timerWidth,
164+
decoration: BoxDecoration(
165+
borderRadius: BorderRadius.circular(Globals.borderRadius),
166+
color: Colors.black,
167+
),
168+
child: Padding(
169+
padding: const EdgeInsets.only(left: 15, right: 25),
170+
child: GestureDetector(
171+
behavior: HitTestBehavior.opaque,
172+
onTap: () async {
173+
var filePath = await Record().stop();
174+
AudioState.files.add(filePath!);
175+
Globals.audioListKey.currentState!
176+
.insertItem(AudioState.files.length - 1);
177+
debugPrint(filePath);
178+
setState(() {
179+
isLocked = false;
180+
});
181+
startTime = null;
182+
recordDuration = "00:00";
183+
timer?.cancel();
184+
},
185+
child: Row(
186+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
187+
mainAxisSize: MainAxisSize.max,
188+
children: [
189+
Text(recordDuration),
190+
FlowShader(
191+
child: const Text("Tap lock to stop"),
192+
duration: const Duration(seconds: 3),
193+
flowColors: const [Colors.white, Colors.grey],
194+
),
195+
const Center(
196+
child: FaIcon(
197+
FontAwesomeIcons.lock,
198+
size: 18,
199+
color: Colors.green,
200+
),
201+
),
202+
],
203+
),
204+
),
205+
),
206+
),
207+
);
208+
}
209+
155210
Widget audioButton() {
156211
return GestureDetector(
157212
child: Transform.scale(
@@ -174,19 +229,25 @@ class _RecordButtonState extends State<RecordButton> {
174229
onLongPressEnd: (details) async {
175230
debugPrint("onLongPressEnd");
176231
widget.controller.reverse();
177-
debugPrint(details.localPosition.toString());
178-
startTime = null;
179-
recordDuration = "00:00";
180-
timer?.cancel();
232+
181233
if (isCancelled(details.localPosition)) {
234+
startTime = null;
235+
recordDuration = "00:00";
236+
timer?.cancel();
182237
debugPrint("Cancelled recording");
183238
var filePath = await record.stop();
184239
debugPrint(filePath);
185240
File(filePath!).delete();
186241
debugPrint("Deleted $filePath");
187-
} else if (isLocked(details.localPosition)) {
242+
} else if (checkIsLocked(details.localPosition)) {
188243
debugPrint("Locked recording");
244+
setState(() {
245+
isLocked = true;
246+
});
189247
} else {
248+
startTime = null;
249+
recordDuration = "00:00";
250+
timer?.cancel();
190251
var filePath = await Record().stop();
191252
AudioState.files.add(filePath!);
192253
Globals.audioListKey.currentState!
@@ -224,7 +285,7 @@ class _RecordButtonState extends State<RecordButton> {
224285
);
225286
}
226287

227-
bool isLocked(Offset offset) {
288+
bool checkIsLocked(Offset offset) {
228289
return (offset.dy < -85 && offset.dy > -135);
229290
}
230291

0 commit comments

Comments
 (0)