Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## [3.0.0] (unreleased)
## [3.0.0]

* **Feat**: [401](https://github.com/SimformSolutionsPvtLtd/chatview/pull/401)
Add selection and copy options for text view.
* **Breaking**: [318](https://github.com/SimformSolutionsPvtLtd/chatview/issues/318)
Expand Down Expand Up @@ -53,6 +54,11 @@
* **Breaking**: [390](https://github.com/SimformSolutionsPvtLtd/chatview/pull/390) `playIcon` and
`pauseIcon` Now accepts a callback that provides different icons based on whether the message is
by the sender or not. accept `Widget`.
* **Feat**: [390](https://github.com/SimformSolutionsPvtLtd/chatview/pull/406) Updated
audio_waveforms version to `2.0.0`
* **Breaking**: [390](https://github.com/SimformSolutionsPvtLtd/chatview/pull/406) Moved recording
audio settings from `VoiceRecordingConfiguration` to `RecorderSettings`. Check out the migration
guide [here](https://simform-flutter-packages.web.app/chatView/migration-guide).

## [2.5.0]

Expand Down
39 changes: 39 additions & 0 deletions doc/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,45 @@ This guide will help you migrate your code from previous versions of ChatView to

## Key Changes

### Voice Recording Configuration

The `VoiceRecordingConfiguration` class has been updated to utilize `RecorderSettings`, which now
encapsulates the recorder settings for both iOS and Android platforms. The `androidOutputFormat`
property has been removed so whatever format will be given by the encoder that will be used.

Previous Usage:
```dart
ChatView(
sendMessageConfig: SendMessageConfiguration(
voiceRecordingConfiguration: VoiceRecordingConfiguration(
sampleRate: 44100,
bitRate: 128000,
iosEncoder: IosEncoder.kAudioFormatMPEG4AAC,
androidEncoder: AndroidEncoder.aacLc,
androidOutputFormat: AndroidOutputFormat.mpeg4,
),
),
```

New Usage:
```dart
ChatView(
sendMessageConfig: SendMessageConfiguration(
voiceRecordingConfiguration: VoiceRecordingConfiguration(
recorderSettings: RecorderSettings(
bitRate: 128000,
sampleRate: 44100,
androidEncoderSettings: AndroidEncoderSettings(
androidEncoder: AndroidEncoder.aacLc,
),
iosEncoderSettings: IosEncoderSetting(
iosEncoder: IosEncoder.kAudioFormatMPEG4AAC,
),
),
),
),
```

### Text Field Action Items

You can now add action buttons to the input field using two builders:
Expand Down
6 changes: 1 addition & 5 deletions example/lib/widgets/custom_chat_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,7 @@ class _CustomChatBarState extends State<CustomChatBar> {
Future<void> _recordOrStop() async {
if (!isRecording.value) {
await controller?.record(
sampleRate: voiceRecordingConfig.sampleRate,
bitRate: voiceRecordingConfig.bitRate,
androidEncoder: voiceRecordingConfig.androidEncoder,
iosEncoder: voiceRecordingConfig.iosEncoder,
androidOutputFormat: voiceRecordingConfig.androidOutputFormat,
recorderSettings: voiceRecordingConfig.recorderSettings,
);
isRecording.value = true;
} else {
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
sdk: flutter
cupertino_icons: ^1.0.5
flutter_svg: ^2.2.1
audio_waveforms: ^1.3.0
audio_waveforms: ^2.0.0
chatview:
path: ../
intl:
Expand Down
4 changes: 3 additions & 1 deletion lib/chatview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ library chatview;
export 'package:audio_waveforms/audio_waveforms.dart'
show
AndroidEncoder,
AndroidOutputFormat,
AndroidEncoderSettings,
IosEncoder,
IosEncoderSetting,
PlayerWaveStyle,
RecorderSettings,
WaveStyle;
export 'package:chatview_utils/chatview_utils.dart'
hide
Expand Down
30 changes: 5 additions & 25 deletions lib/src/models/config_models/send_message_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import '../../values/typedefs.dart';

class SendMessageConfiguration {
const SendMessageConfiguration({
this.voiceRecordingConfiguration = const VoiceRecordingConfiguration(),
this.shouldSendImageWithText = false,
this.allowRecordingVoice = true,
this.textFieldConfig,
Expand All @@ -42,7 +43,6 @@ class SendMessageConfiguration {
this.replyTitleColor,
this.replyMessageColor,
this.closeIconColor,
this.voiceRecordingConfiguration,
this.micIconColor,
this.cancelRecordConfiguration,
this.removeImageIcon,
Expand Down Expand Up @@ -92,7 +92,7 @@ class SendMessageConfiguration {
final Color? micIconColor;

/// Styling configuration for recorder widget.
final VoiceRecordingConfiguration? voiceRecordingConfiguration;
final VoiceRecordingConfiguration voiceRecordingConfiguration;

/// Configuration for cancel voice recording
final CancelRecordConfiguration? cancelRecordConfiguration;
Expand Down Expand Up @@ -271,6 +271,7 @@ class VoiceRecordingConfiguration {
/// Styling configuration for the recorder widget as well as
/// configuring the audio recording quality.
const VoiceRecordingConfiguration({
this.recorderSettings = const RecorderSettings(),
this.waveStyle,
this.padding,
this.margin,
Expand All @@ -279,11 +280,6 @@ class VoiceRecordingConfiguration {
this.micIcon,
this.recorderIconColor,
this.stopIcon,
this.sampleRate,
this.bitRate,
this.androidEncoder,
this.iosEncoder,
this.androidOutputFormat,
});

/// Applies styles to waveform.
Expand Down Expand Up @@ -311,24 +307,8 @@ class VoiceRecordingConfiguration {
/// Applies color to mic and stop icon.
final Color? recorderIconColor;

/// The sample rate for audio is measured in samples per second.
/// A higher sample rate generates more samples per second,
/// resulting in better audio quality but also larger file sizes.
final int? sampleRate;

/// Bitrate is the amount of data per second that the codec uses to
/// encode the audio. A higher bitrate results in better quality
/// but also larger file sizes.
final int? bitRate;

/// Audio encoder to be used for recording for IOS.
final IosEncoder? iosEncoder;

/// Audio encoder to be used for recording for Android.
final AndroidEncoder? androidEncoder;

/// The audio output format to be used for recorded audio files on Android.
final AndroidOutputFormat? androidOutputFormat;
/// Configures audio recording settings for Android and iOS.
final RecorderSettings recorderSettings;
}

class CancelRecordConfiguration {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/widgets/chat_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ class ChatView extends StatefulWidget {
this.appBar,
ChatBackgroundConfiguration? chatBackgroundConfig,
this.sendMessageBuilder,
this.sendMessageConfig,
this.onChatListTap,
required this.chatViewState,
ChatViewStateConfiguration? chatViewStateConfig,
this.featureActiveConfig = const FeatureActiveConfig(),
this.sendMessageConfig = const SendMessageConfiguration(),
this.emojiPickerSheetConfig,
this.replyMessageBuilder,
this.replySuggestionsConfig,
Expand Down Expand Up @@ -123,7 +123,7 @@ class ChatView extends StatefulWidget {
final ChatController chatController;

/// Provides configuration of default text field in chat.
final SendMessageConfiguration? sendMessageConfig;
final SendMessageConfiguration sendMessageConfig;

/// Provides current state of chat.
final ChatViewState chatViewState;
Expand Down Expand Up @@ -296,7 +296,7 @@ class _ChatViewState extends State<ChatView>
_sendMessageKey.currentState
?.assignReplyMessage(message),
textFieldConfig:
widget.sendMessageConfig?.textFieldConfig,
widget.sendMessageConfig.textFieldConfig,
),
),
if (featureActiveConfig.enableTextField)
Expand Down
61 changes: 28 additions & 33 deletions lib/src/widgets/chatui_textfield.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ class ChatUITextField extends StatefulWidget {
required this.onPressed,
required this.onRecordingComplete,
required this.onImageSelected,
this.sendMessageConfig,
required this.sendMessageConfig,
super.key,
});

/// Provides configuration of default text field in chat.
final SendMessageConfiguration? sendMessageConfig;
final SendMessageConfiguration sendMessageConfig;

/// Provides focusNode for focusing text field.
final FocusNode focusNode;
Expand Down Expand Up @@ -80,23 +80,23 @@ class _ChatUITextFieldState extends State<ChatUITextField> {

bool Function(KeyEvent)? _keyboardHandler;

SendMessageConfiguration? get sendMessageConfig => widget.sendMessageConfig;
SendMessageConfiguration get sendMessageConfig => widget.sendMessageConfig;

VoiceRecordingConfiguration? get voiceRecordingConfig =>
widget.sendMessageConfig?.voiceRecordingConfiguration;
VoiceRecordingConfiguration get voiceRecordingConfig =>
widget.sendMessageConfig.voiceRecordingConfiguration;

ImagePickerIconsConfiguration? get imagePickerIconsConfig =>
sendMessageConfig?.imagePickerIconsConfig;
sendMessageConfig.imagePickerIconsConfig;

TextFieldConfiguration? get textFieldConfig =>
sendMessageConfig?.textFieldConfig;
sendMessageConfig.textFieldConfig;

CancelRecordConfiguration? get cancelRecordConfiguration =>
sendMessageConfig?.cancelRecordConfiguration;
sendMessageConfig.cancelRecordConfiguration;

OutlineInputBorder get _outLineBorder => OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: widget.sendMessageConfig?.textFieldConfig?.borderRadius ??
borderRadius: widget.sendMessageConfig.textFieldConfig?.borderRadius ??
BorderRadius.circular(textFieldBorderRadius),
);

Expand All @@ -112,7 +112,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
// onChanged is not called when text is set programmatically.
widget.textEditingController.addListener(_listenTextEditingController);
debouncer = Debouncer(
sendMessageConfig?.textFieldConfig?.compositionThresholdTime ??
sendMessageConfig.textFieldConfig?.compositionThresholdTime ??
const Duration(seconds: 1));
super.initState();

Expand Down Expand Up @@ -142,7 +142,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {

void attachListeners() {
composingStatus.addListener(() {
widget.sendMessageConfig?.textFieldConfig?.onMessageTyping
widget.sendMessageConfig.textFieldConfig?.onMessageTyping
?.call(composingStatus.value);
});
}
Expand Down Expand Up @@ -198,7 +198,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
decoration: BoxDecoration(
borderRadius: textFieldConfig?.borderRadius ??
BorderRadius.circular(textFieldBorderRadius),
color: sendMessageConfig?.textFieldBackgroundColor ?? Colors.white,
color: sendMessageConfig.textFieldBackgroundColor ?? Colors.white,
),
child: ChatTextFieldViewBuilder<bool>(
valueListenable: isRecording,
Expand All @@ -210,22 +210,22 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
child: AudioWaveforms(
size: const Size(double.maxFinite, 50),
recorderController: controller!,
margin: voiceRecordingConfig?.margin,
padding: voiceRecordingConfig?.padding ??
margin: voiceRecordingConfig.margin,
padding: voiceRecordingConfig.padding ??
EdgeInsets.symmetric(
horizontal: cancelRecordConfiguration == null ? 8 : 5,
),
decoration: voiceRecordingConfig?.decoration ??
decoration: voiceRecordingConfig.decoration ??
BoxDecoration(
color: voiceRecordingConfig?.backgroundColor,
color: voiceRecordingConfig.backgroundColor,
borderRadius: BorderRadius.circular(12),
),
waveStyle: voiceRecordingConfig?.waveStyle ??
waveStyle: voiceRecordingConfig.waveStyle ??
WaveStyle(
extendWaveform: true,
showMiddleLine: false,
waveColor:
voiceRecordingConfig?.waveStyle?.waveColor ??
voiceRecordingConfig.waveStyle?.waveColor ??
Colors.black,
),
),
Expand Down Expand Up @@ -271,7 +271,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
hintText: textFieldConfig?.hintText ??
PackageStrings.currentLocale.message,
fillColor:
sendMessageConfig?.textFieldBackgroundColor ??
sendMessageConfig.textFieldBackgroundColor ??
Colors.white,
filled: true,
hintMaxLines: textFieldConfig?.hintMaxLines ?? 1,
Expand Down Expand Up @@ -300,13 +300,13 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
builder: (_, isNotEmpty, child) {
if (isNotEmpty) {
return IconButton(
color: sendMessageConfig?.defaultSendButtonColor ??
color: sendMessageConfig.defaultSendButtonColor ??
Colors.green,
style: sendMessageConfig?.sendButtonStyle,
style: sendMessageConfig.sendButtonStyle,
onPressed: (textFieldConfig?.enabled ?? true)
? _onPressed
: null,
icon: sendMessageConfig?.sendButtonIcon ??
icon: sendMessageConfig.sendButtonIcon ??
const Icon(Icons.send),
);
} else {
Expand Down Expand Up @@ -353,20 +353,19 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
],

// Always add the voice button at the end if allowed
if ((sendMessageConfig?.allowRecordingVoice ?? false) &&
if ((sendMessageConfig.allowRecordingVoice) &&
!kIsWeb &&
(Platform.isIOS || Platform.isAndroid))
IconButton(
onPressed: (textFieldConfig?.enabled ?? true)
? _recordOrStop
: null,
icon: (isRecordingValue
? voiceRecordingConfig?.stopIcon
: voiceRecordingConfig?.micIcon) ??
? voiceRecordingConfig.stopIcon
: voiceRecordingConfig.micIcon) ??
Icon(
isRecordingValue ? Icons.stop : Icons.mic,
color:
voiceRecordingConfig?.recorderIconColor,
color: voiceRecordingConfig.recorderIconColor,
),
),

Expand All @@ -380,7 +379,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
icon: cancelRecordConfiguration?.icon ??
const Icon(Icons.cancel_outlined),
color: cancelRecordConfiguration?.iconColor ??
voiceRecordingConfig?.recorderIconColor,
voiceRecordingConfig.recorderIconColor,
),
],
);
Expand Down Expand Up @@ -428,11 +427,7 @@ class _ChatUITextFieldState extends State<ChatUITextField> {
);
if (!isRecording.value) {
await controller?.record(
sampleRate: voiceRecordingConfig?.sampleRate,
bitRate: voiceRecordingConfig?.bitRate,
androidEncoder: voiceRecordingConfig?.androidEncoder,
iosEncoder: voiceRecordingConfig?.iosEncoder,
androidOutputFormat: voiceRecordingConfig?.androidOutputFormat,
recorderSettings: voiceRecordingConfig.recorderSettings,
);
isRecording.value = true;
} else {
Expand Down
Loading