flutter_message_composer 0.2.2 copy "flutter_message_composer: ^0.2.2" to clipboard
flutter_message_composer: ^0.2.2 copied to clipboard

An adaptive Flutter message composer with multiline text, attachments, audio previews, and hold-to-record gestures with slide-to-cancel and locking.

flutter_message_composer #

An adaptive Flutter message composer for chat and messaging experiences. It provides multiline text input, configurable actions, typed submissions, and tap-or-hold audio recording with playback previews. It is independent of networking, storage, and state management.

The package currently targets Android and iOS.

Features #

  • Compact input that animates into a multiline composer.
  • Configurable attachment menu and prompt actions.
  • Text, attachment, and recorded-audio submission payloads.
  • Tap to manage a recording or hold to record and send on release.
  • Slide toward cancel to discard a held recording, or upward to lock it and continue hands-free without sending on release.
  • Stop, play, pause, resume, and replay audio before sending.
  • Tabular MM:SS recording and playback times beside the waveform.
  • Playback progress and theme-aware recording-lock feedback.
  • Disabled and sending states.
  • Theme-aware defaults with optional colors, shapes, icons, and tooltips.
  • A customizable suggestion area for mentions, hashtags, commands, quick replies, or any other contextual content.
  • Callbacks for typing, recording lifecycle, permission denial, and errors.
  • An injectable recorder contract for custom native or DSP-backed capture.
  • A lazily created, injectable audio preview player.
  • No dependency on a chat backend or state-management package.

Installation #

Add the published package to pubspec.yaml:

dependencies:
  flutter_message_composer: ^0.2.2

Platform setup #

Audio recording uses the record package. Android requires API 23 or newer and the microphone permission in android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

iOS requires version 12.0 or newer and a usage description in ios/Runner/Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>Audio messages require access to the microphone.</string>

Usage #

import 'package:flutter/material.dart';
import 'package:flutter_message_composer/flutter_message_composer.dart';

final controller = TextEditingController();
final focusNode = FocusNode();

MessageComposer(
  controller: controller,
  focusNode: focusNode,
  hintText: 'Message',
  sendTooltip: 'Send',
  attachTooltip: 'Attachments',
  recordTooltip: 'Record audio',
  suggestions: activeSuggestions.isEmpty
      ? null
      : SuggestionsList(
          suggestions: activeSuggestions,
          onSelected: handleSuggestion,
        ),
  menuActions: [
    ChatInputMenuAction(
      id: 'photo',
      label: 'Photo',
      icon: const Icon(Icons.image_outlined),
      onPressed: pickPhoto,
    ),
  ],
  attachments: selectedAttachments,
  onChanged: handleTyping,
  onSend: (submission) {
    if (submission.hasAudio) {
      uploadAndSendAudio(submission.audio!);
      return;
    }

    sendMessage(
      text: submission.text,
      attachments: submission.attachments,
    );
  },
)

The suggestions property accepts a widget for displaying and selecting suggestions. Pass null when none are active and the area collapses automatically. The controller property accepts any TextEditingController, including specialized token-aware controllers. No text parser is required by this package.

The caller owns attachment picking, uploads, message creation, retries, and clearing the text controller after a submission is accepted. Pass sending: true to temporarily lock the composer while an operation is in progress.

The default recorder uses record. To customize capture or audio processing, implement MessageComposerRecorder and provide an isolated instance with audioRecorderFactory. The composer owns and disposes the returned backend.

Audio workflows #

  • Tap the microphone: record until Stop, Send, or Cancel is pressed.
  • Hold the microphone: record and send once when the same finger releases.
  • Slide toward Cancel: discard immediately after the horizontal threshold. This direction is left in left-to-right layouts and right in right-to-left layouts, matching the cancel button.
  • Slide upward: lock recording. Releasing the finger does not send; Stop, Send, and Cancel remain available.
  • Stop: show Play and the recording's total duration.
  • Play / Pause: listen before sending, resume from the paused position, or replay from the start after completion. Playback never submits audio.

The time before the waveform is elapsed recording time, current playback time while playing or paused, and total duration while stopped or completed. Minutes and seconds have at least two digits (01:03); recordings longer than an hour keep their total minutes (61:03).

Sending or canceling stops the preview first. Canceling or removing the composer discards its unsent recording. Once onSend receives an audio submission, the callback recipient owns that file and is responsible for its eventual cleanup. Releasing while permission or microphone startup is pending preserves the user's send, cancel, or lock intent without duplicate submissions.

Customization #

The new options are optional. Existing MessageComposer calls gain previews and recording gestures without additional setup.

MessageComposer(
  controller: controller,
  focusNode: focusNode,
  hintText: 'Message',
  recordingCancelDragDistance: 96,
  recordingLockDragDistance: 80,
  enableRecordingHaptics: true,
  recordingTimerStyle: const TextStyle(fontWeight: FontWeight.w600),
  cancelRecordingTooltip: 'Cancel',
  stopRecordingTooltip: 'Stop recording',
  playRecordingTooltip: 'Play audio',
  pauseRecordingTooltip: 'Pause audio',
  sendRecordingTooltip: 'Send audio',
  lockRecordingLabel: 'Lock recording',
  recordingLockedLabel: 'Recording locked',
  onRecordingLocked: handleRecordingLocked,
  onAudioPreviewError: handlePreviewError,
  onSend: handleSubmission,
)

Use playRecordingButtonIcon and pauseRecordingButtonIcon to replace the default icons, alongside the existing cancel, stop, and send icon overrides. The timer style merges with the theme and tabular-digit defaults. Gesture distances are positive logical pixels. Light-impact feedback confirms that a held recording has started and when a cancel or lock threshold is reached. Start feedback waits for microphone permission and successful capture; it is not emitted for failed starts or recordings already queued to send or cancel. Haptics can be disabled with enableRecordingHaptics: false.

On iOS 13 and later, the default recorder permits haptics during capture so locking a held recording can produce feedback without stopping the microphone. The iOS setting also permits system sounds during recording. Explicit RecordConfig.iosConfig values are preserved; custom recorder implementations must configure their audio session to allow haptics. Setting enableRecordingHaptics: false disables the composer's gesture feedback.

Previews use audioplayers. For another backend, implement MessageComposerPlayer and supply audioPlayerFactory. Report position changes and playback states, including pauses caused by native interruptions and completion. The composer owns the player but creates it only when the first preview is requested. onAudioPreviewError handles preview failures separately from capture errors and leaves the audio available to retry, send, or discard.

Recording labels have English defaults. Set the label and tooltip parameters to provide localized text. See example/lib/main.dart for a complete usage example.

Scope #

flutter_message_composer is a presentation component. It does not prescribe a message model, networking client, storage layer, or state-management solution. Submissions and lifecycle callbacks provide the integration points.

1
likes
0
points
392
downloads

Publisher

unverified uploader

Weekly Downloads

An adaptive Flutter message composer with multiline text, attachments, audio previews, and hold-to-record gestures with slide-to-cancel and locking.

Homepage

Topics

#chat #messaging #composer #audio-recording #user-interface

License

unknown (license)

Dependencies

audioplayers, flutter, hugeicons, path_provider, record

More

Packages that depend on flutter_message_composer