@@ -89,8 +89,6 @@ class StreamAudioRecorderButton extends StatelessWidget {
89
89
90
90
@override
91
91
Widget build (BuildContext context) {
92
- final theme = StreamChatTheme .of (context);
93
-
94
92
final isRecording = recordState is ! RecordStateIdle ;
95
93
final isLocked = isRecording && recordState is ! RecordStateRecordingHold ;
96
94
@@ -128,13 +126,9 @@ class StreamAudioRecorderButton extends StatelessWidget {
128
126
},
129
127
child: StreamAudioRecorderBuilder (
130
128
state: recordState,
131
- button: StreamSvgIcon (
132
- icon: StreamSvgIcons .mic,
133
- size: kDefaultMessageInputIconSize,
134
- color: switch (isRecording) {
135
- true => theme.colorTheme.accentPrimary,
136
- false => theme.colorTheme.textLowEmphasis,
137
- },
129
+ button: StreamMessageInputIconButton (
130
+ onPressed: () {}, // Allows showing ripple effect on tap.
131
+ icon: const StreamSvgIcon (icon: StreamSvgIcons .mic),
138
132
),
139
133
builder: (context, state, recordButton) => switch (state) {
140
134
// Show only the record button if the recording is not in progress.
@@ -188,16 +182,23 @@ class RecordStateIdleContent extends StatelessWidget {
188
182
189
183
@override
190
184
Widget build (BuildContext context) {
185
+ final theme = StreamChatTheme .of (context);
186
+
187
+ final child = IconTheme (
188
+ data: IconThemeData (color: theme.colorTheme.textLowEmphasis),
189
+ child: recordButton,
190
+ );
191
+
191
192
final info = state.message;
192
- if (info == null || info.isEmpty) return recordButton ;
193
+ if (info == null || info.isEmpty) return child ;
193
194
194
195
return PortalTarget (
195
196
anchor: const Aligned (
196
197
target: Alignment .topRight,
197
198
follower: Alignment .bottomRight,
198
199
),
199
200
portalFollower: HoldToRecordInfoTooltip (message: info),
200
- child: recordButton ,
201
+ child: child ,
201
202
);
202
203
}
203
204
}
@@ -246,7 +247,7 @@ class RecordStateHoldRecordingContent extends StatelessWidget {
246
247
// Show the swipe to lock button once the recording starts.
247
248
visible: recordingTime.inSeconds > 0 ,
248
249
anchor: Aligned (
249
- offset: Offset (0 , dragOffset.dy - 16 ),
250
+ offset: Offset (4 , dragOffset.dy - 16 ),
250
251
target: Alignment .topRight,
251
252
follower: Alignment .bottomRight,
252
253
),
@@ -257,19 +258,25 @@ class RecordStateHoldRecordingContent extends StatelessWidget {
257
258
),
258
259
child: Row (
259
260
children: [
260
- PlaybackTimerIndicator (duration: recordingTime),
261
+ IgnorePointer (
262
+ child: PlaybackTimerIndicator (duration: recordingTime),
263
+ ),
261
264
Expanded (
262
- child: SlideToCancelIndicator (
263
- progress: cancelProgress.toDouble (),
265
+ child: IgnorePointer (
266
+ child: SlideToCancelIndicator (
267
+ progress: cancelProgress.toDouble (),
268
+ ),
264
269
),
265
270
),
266
- Container (
267
- padding: const EdgeInsets .all (8 ),
271
+ DecoratedBox (
268
272
decoration: BoxDecoration (
269
273
shape: BoxShape .circle,
270
274
color: theme.colorTheme.inputBg,
271
275
),
272
- child: recordButton,
276
+ child: IconTheme (
277
+ data: IconThemeData (color: theme.colorTheme.accentPrimary),
278
+ child: recordButton,
279
+ ),
273
280
),
274
281
].insertBetween (const SizedBox (width: 8 )),
275
282
),
@@ -316,7 +323,7 @@ class RecordStateLockedRecordingContent extends StatelessWidget {
316
323
317
324
return PortalTarget (
318
325
anchor: const Aligned (
319
- offset: Offset (0 , - 16 ),
326
+ offset: Offset (4 , - 16 ),
320
327
target: Alignment .topRight,
321
328
follower: Alignment .bottomRight,
322
329
),
@@ -335,7 +342,7 @@ class RecordStateLockedRecordingContent extends StatelessWidget {
335
342
const SizedBox (width: 8 ),
336
343
Expanded (
337
344
child: SizedBox (
338
- height: 28 ,
345
+ height: kDefaultMessageInputIconSize ,
339
346
child: StreamAudioWaveform (
340
347
limit: 50 ,
341
348
waveform: state.waveform,
@@ -429,7 +436,7 @@ class _RecordStateStoppedContentState extends State<RecordStateStoppedContent> {
429
436
430
437
return PortalTarget (
431
438
anchor: const Aligned (
432
- offset: Offset (0 , - 16 ),
439
+ offset: Offset (4 , - 16 ),
433
440
target: Alignment .topRight,
434
441
follower: Alignment .bottomRight,
435
442
),
@@ -505,7 +512,7 @@ class _RecordStateStoppedContentState extends State<RecordStateStoppedContent> {
505
512
);
506
513
},
507
514
),
508
- const SizedBox (height: 8 ),
515
+ const SizedBox (height: 2 ),
509
516
Row (
510
517
mainAxisAlignment: MainAxisAlignment .spaceBetween,
511
518
children: [
@@ -619,15 +626,21 @@ class PlaybackControlButton extends StatelessWidget {
619
626
TrackState .paused => onPlay,
620
627
},
621
628
icon: switch (state) {
622
- TrackState .loading => SizedBox .fromSize (
623
- size: const Size .square (24 - /* Padding */ 2 ),
624
- child: Center (
625
- child: CircularProgressIndicator .adaptive (
626
- valueColor: AlwaysStoppedAnimation (
627
- theme.colorTheme.accentPrimary,
629
+ TrackState .loading => Builder (
630
+ builder: (context) {
631
+ final iconTheme = IconTheme .of (context);
632
+ return SizedBox .fromSize (
633
+ size: Size .square (iconTheme.size! ),
634
+ child: Padding (
635
+ padding: const EdgeInsets .all (8 ),
636
+ child: CircularProgressIndicator .adaptive (
637
+ valueColor: AlwaysStoppedAnimation (
638
+ theme.colorTheme.accentPrimary,
639
+ ),
640
+ ),
628
641
),
629
- ),
630
- ) ,
642
+ );
643
+ } ,
631
644
),
632
645
TrackState .idle => const StreamSvgIcon (icon: StreamSvgIcons .play),
633
646
TrackState .paused => const StreamSvgIcon (icon: StreamSvgIcons .play),
@@ -884,7 +897,10 @@ class HoldToRecordInfoTooltip extends StatelessWidget {
884
897
Widget build (BuildContext context) {
885
898
final theme = StreamChatTheme .of (context);
886
899
887
- const arrowSize = Size (kDefaultMessageInputIconSize / 2 , 6 );
900
+ const recordButtonWidth = kDefaultMessageInputIconSize +
901
+ kDefaultMessageInputIconPadding * 2 ; // right, left padding.
902
+
903
+ const arrowSize = Size (recordButtonWidth / 2 , 6 );
888
904
889
905
return Padding (
890
906
padding: EdgeInsets .only (bottom: arrowSize.height),
0 commit comments