build method

  1. @override
Widget build(
  1. BuildContext context
)
override

chat bubble builder method

Implementation

@override
Widget build(BuildContext context) {
  bool stateTick = false;
  Icon? stateIcon;
  if (sent) {
    stateTick = true;
    stateIcon = Icon(
      Icons.done,
      size: 18,
      color: Color(0xFF97AD8E),
    );
  }
  if (delivered) {
    stateTick = true;
    stateIcon = Icon(
      Icons.done_all,
      size: 18,
      color: Color(0xFF97AD8E),
    );
  }
  if (seen) {
    stateTick = true;
    stateIcon = Icon(
      Icons.done_all,
      size: 18,
      color: Color(0xFF92DEDA),
    );
  }

  final bool showStatusArea = stateTick || timestamp != null || isEdited;
  final Color forwardedColor =
      (textStyle.color ?? Colors.black87).withOpacity(0.6);

  final double dur = duration ?? 0.0;
  final double pos = position ?? 0.0;
  final double waveProgress = dur > 0 ? (pos / dur).clamp(0.0, 1.0) : 0.0;

  return Row(
    children: <Widget>[
      isSender
          ? Expanded(
              child: SizedBox(
                width: 5,
              ),
            )
          : Container(),
      Container(
        color: Colors.transparent,
        constraints: constraints ??
            BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .8),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
          child: Container(
            decoration: BoxDecoration(
              color: color,
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(bubbleRadius),
                topRight: Radius.circular(bubbleRadius),
                bottomLeft: Radius.circular(tail
                    ? isSender
                        ? bubbleRadius
                        : 0
                    : defaultBubbleRadiusAudio),
                bottomRight: Radius.circular(tail
                    ? isSender
                        ? 0
                        : bubbleRadius
                    : defaultBubbleRadiusAudio),
              ),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                if (isForwarded)
                  Padding(
                    padding: const EdgeInsets.fromLTRB(12, 8, 12, 0),
                    child: BubbleForwardedHeader(color: forwardedColor),
                  ),
                // Player row: play/pause button + waveform or slider
                Row(
                  children: [
                    // Playback speed button (shown before play button when enabled)
                    if (showPlaybackSpeed)
                      GestureDetector(
                        onTap: onPlaybackSpeedChanged != null
                            ? () {
                                final double next =
                                    playbackSpeed >= 2.0
                                        ? 1.0
                                        : playbackSpeed >= 1.5
                                            ? 2.0
                                            : 1.5;
                                onPlaybackSpeedChanged!(next);
                              }
                            : null,
                        child: Container(
                          margin: const EdgeInsets.only(left: 8),
                          padding: const EdgeInsets.symmetric(
                              horizontal: 6, vertical: 2),
                          decoration: BoxDecoration(
                            border: Border.all(
                                color: textStyle.color ?? Colors.black54,
                                width: 1),
                            borderRadius: BorderRadius.circular(4),
                          ),
                          child: Text(
                            _speedLabel(playbackSpeed),
                            style: TextStyle(
                              fontSize: 11,
                              fontWeight: FontWeight.bold,
                              color: textStyle.color ?? Colors.black87,
                            ),
                          ),
                        ),
                      ),
                    RawMaterialButton(
                      onPressed: onPlayPauseButtonClick,
                      elevation: 1.0,
                      fillColor: Colors.white,
                      padding: EdgeInsets.all(0.0),
                      shape: CircleBorder(),
                      child: !isPlaying
                          ? Icon(Icons.play_arrow, size: 30.0)
                          : isLoading
                              ? CircularProgressIndicator()
                              : isPause
                                  ? Icon(Icons.play_arrow, size: 30.0)
                                  : Icon(Icons.pause, size: 30.0),
                    ),
                    Expanded(
                      child: waveformData != null && waveformData!.isNotEmpty
                          ? _buildWaveform(waveformData!, waveProgress, dur)
                          : Slider(
                              min: 0.0,
                              max: dur,
                              value: pos,
                              onChanged: onSeekChanged,
                            ),
                    ),
                  ],
                ),
                // Bottom row: audio timer + status
                Padding(
                  padding: const EdgeInsets.fromLTRB(12, 0, 8, 8),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        audioTimer(dur, pos),
                        style: textStyle,
                      ),
                      if (showStatusArea)
                        BubbleStatusRow(
                          stateIcon: stateTick ? stateIcon : null,
                          isEdited: isEdited,
                          timestamp: timestamp,
                          textColor: textStyle.color ?? Colors.black87,
                        ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ],
  );
}