90 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'dart:math' as math;
 | 
						|
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:island/database/message.dart';
 | 
						|
import 'package:island/models/embed.dart';
 | 
						|
import 'package:island/utils/mapping.dart';
 | 
						|
import 'package:island/widgets/chat/message_content.dart';
 | 
						|
import 'package:island/widgets/chat/message_sender_info.dart';
 | 
						|
import 'package:island/widgets/content/cloud_file_collection.dart';
 | 
						|
import 'package:island/widgets/content/cloud_files.dart';
 | 
						|
import 'package:island/widgets/content/embed/link.dart';
 | 
						|
 | 
						|
class MessageListTile extends StatelessWidget {
 | 
						|
  final LocalChatMessage message;
 | 
						|
  final Function(String messageId) onJump;
 | 
						|
 | 
						|
  const MessageListTile({
 | 
						|
    super.key,
 | 
						|
    required this.message,
 | 
						|
    required this.onJump,
 | 
						|
  });
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    final remoteMessage = message.toRemoteMessage();
 | 
						|
    final sender = remoteMessage.sender;
 | 
						|
 | 
						|
    return ListTile(
 | 
						|
      isThreeLine: true,
 | 
						|
      leading: CircleAvatar(
 | 
						|
        radius: 20,
 | 
						|
        backgroundColor: Colors.transparent,
 | 
						|
        child: ProfilePictureWidget(
 | 
						|
          fileId: sender.account.profile.picture?.id,
 | 
						|
          radius: 20,
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
      title: Column(
 | 
						|
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
        children: [
 | 
						|
          MessageSenderInfo(
 | 
						|
            sender: sender,
 | 
						|
            createdAt: message.createdAt,
 | 
						|
            textColor: Theme.of(context).colorScheme.onSurfaceVariant,
 | 
						|
            showAvatar: false,
 | 
						|
            isCompact: true,
 | 
						|
          ),
 | 
						|
          const SizedBox(height: 4),
 | 
						|
          MessageContent(item: remoteMessage, isSelectable: false),
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
      subtitle: Column(
 | 
						|
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
        children: [
 | 
						|
          if (remoteMessage.attachments.isNotEmpty)
 | 
						|
            LayoutBuilder(
 | 
						|
              builder: (context, constraints) {
 | 
						|
                return CloudFileList(
 | 
						|
                  files: remoteMessage.attachments,
 | 
						|
                  maxWidth: constraints.maxWidth,
 | 
						|
                  padding: EdgeInsets.symmetric(vertical: 4),
 | 
						|
                );
 | 
						|
              },
 | 
						|
            ),
 | 
						|
          if (remoteMessage.meta['embeds'] != null)
 | 
						|
            ...((remoteMessage.meta['embeds'] as List<dynamic>)
 | 
						|
                .map((embed) => convertMapKeysToSnakeCase(embed))
 | 
						|
                .where((embed) => embed['type'] == 'link')
 | 
						|
                .map((embed) => SnScrappedLink.fromJson(embed))
 | 
						|
                .map(
 | 
						|
                  (link) => LayoutBuilder(
 | 
						|
                    builder: (context, constraints) {
 | 
						|
                      return EmbedLinkWidget(
 | 
						|
                        link: link,
 | 
						|
                        maxWidth: math.min(constraints.maxWidth, 480),
 | 
						|
                        margin: const EdgeInsets.symmetric(vertical: 4),
 | 
						|
                      );
 | 
						|
                    },
 | 
						|
                  ),
 | 
						|
                )
 | 
						|
                .toList()),
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
      onTap: () => onJump(message.id),
 | 
						|
      contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
 | 
						|
      dense: true,
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |