mediaAttachment static method

Widget mediaAttachment(
  1. BuildContext context, {
  2. required Attachment attachment,
  3. GlobalKey<State<StatefulWidget>>? key,
  4. ChatItem? item,
  5. Paginated<ChatItemId, Rx<ChatItem>> onGallery()?,
  6. Future<void> onError(
    1. ChatItem?
    )?,
  7. bool filled = true,
  8. bool cover = false,
  9. void onReply(
    1. Post
    )?,
  10. void onShare(
    1. Post
    )?,
  11. void onScrollTo(
    1. Post
    )?,
})

Returns a visual representation of the provided media-Attachment.

Implementation

static Widget mediaAttachment(
  BuildContext context, {
  required Attachment attachment,
  GlobalKey? key,
  ChatItem? item,
  Paginated<ChatItemId, Rx<ChatItem>> Function()? onGallery,
  Future<void> Function(ChatItem?)? onError,
  bool filled = true,
  bool cover = false,
  void Function(Post)? onReply,
  void Function(Post)? onShare,
  void Function(Post)? onScrollTo,
}) {
  final style = Theme.of(context).style;

  final bool isLocal = attachment is LocalAttachment;

  final bool isVideo;
  if (isLocal) {
    isVideo = attachment.file.isVideo;
  } else {
    isVideo = attachment is! ImageAttachment;
  }

  final Widget child = KeyedSubtree(
    key: !isLocal ? const Key('SentImage') : null,
    child: MediaAttachment(
      key: key,
      attachment: attachment,
      width: (cover && isVideo) || filled ? double.infinity : null,
      height: filled ? double.infinity : null,
      onError: () async => await onError?.call(null),
      autoplay: !filled,
    ),
  );

  return Padding(
    padding: EdgeInsets.zero,
    child: MouseRegion(
      cursor: isLocal ? MouseCursor.defer : SystemMouseCursors.click,
      child: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: isLocal
            ? null
            : () {
                if (onGallery == null) {
                  // [onTap] still needs to be invoked to ensure [ContextMenu]
                  // doesn't get closed, when this is being built within it.
                  return;
                }

                int initial = 0;
                if (item is ChatMessage) {
                  initial = max(0, item.attachments.indexOf(attachment));
                }

                PlayerView.show(
                  context,
                  gallery: PaginatedGallery(
                    paginated: onGallery(),
                    resourceId: ResourceId(chatId: item?.chatId),
                    initial: item == null
                        ? null
                        : (item.key.toString(), initial),
                    onReply: onReply,
                    onShare: onShare,
                    onScrollTo: onScrollTo,
                  ),
                );
              },
        child: Stack(
          alignment: Alignment.center,
          children: [
            filled
                ? Positioned.fill(child: child)
                : Container(
                    constraints: const BoxConstraints(minWidth: 300),
                    width: double.infinity,
                    child: child,
                  ),
            ElasticAnimatedSwitcher(
              key: Key('AttachmentStatus_${attachment.id}'),
              child: !isLocal || attachment.status.value == SendingStatus.sent
                  ? Container(key: const Key('Sent'))
                  : Container(
                      constraints: filled
                          ? const BoxConstraints(
                              minWidth: 300,
                              minHeight: 300,
                            )
                          : null,
                      child: attachment.status.value == SendingStatus.sending
                          ? SizedBox(
                              width: 60,
                              height: 60,
                              child: Center(
                                child: CircularProgressIndicator(
                                  key: const Key('Sending'),
                                  value: attachment.progress.value,
                                  backgroundColor: style.colors.onPrimary,
                                  strokeWidth: 10,
                                ),
                              ),
                            )
                          : Icon(
                              Icons.error,
                              key: const Key('Error'),
                              size: 48,
                              color: style.colors.danger,
                            ),
                    ),
            ),
          ],
        ),
      ),
    ),
  );
}