// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat // // SPDX-License-Identifier: AGPL-3.0-or-later import 'package:material_ui/material_ui.dart'; import 'package:matrix/matrix.dart'; import 'package:tatchat/config/app_config.dart'; import 'package:tatchat/l10n/l10n.dart'; import 'package:tatchat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:tatchat/widgets/avatar.dart'; /// A row that represents a mural in the murals list. /// /// The first line shows the circular avatar, the mural name, the creator and /// the number of subscribers. The second line is reserved for the description. /// All colors are taken from the app theme, mirroring the regular chat list /// rows. class MuralListItem extends StatelessWidget { final Room room; final bool activeChat; final void Function() onTap; final void Function(BuildContext context)? onLongPress; final Uri? displayAvatar; final String? displayAvatarName; final String? description; final String? creatorName; const MuralListItem( this.room, { this.activeChat = false, required this.onTap, this.onLongPress, this.displayAvatar, this.displayAvatarName, this.description, this.creatorName, super.key, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final l10n = L10n.of(context); final displayname = room.getLocalizedDisplayname(MatrixLocals(l10n)); final isMuted = room.pushRuleState != PushRuleState.notify; final backgroundColor = activeChat ? theme.colorScheme.secondaryContainer : theme.colorScheme.surface; final description = this.description; final creatorName = this.creatorName; final followers = room.summary.mJoinedMemberCount ?? 0; final mutedStyle = theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ); return Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Material( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppConfig.borderRadius), side: BorderSide( color: theme.colorScheme.surfaceContainer, width: 1.5, ), ), clipBehavior: Clip.hardEdge, color: backgroundColor, child: InkWell( onTap: onTap, onLongPress: onLongPress == null ? null : () => onLongPress?.call(context), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Avatar( mxContent: displayAvatar ?? room.avatar, name: displayAvatarName ?? displayname, size: Avatar.defaultSize, shapeBorder: const CircleBorder(), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Expanded( flex: 3, child: Text( displayname, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ), if (isMuted) const Padding( padding: EdgeInsets.only(left: 4), child: Icon( Icons.notifications_off_outlined, size: 16, ), ), if (room.isFavourite) Padding( padding: const EdgeInsets.only(left: 4), child: Icon( Icons.push_pin, size: 16, color: theme.colorScheme.primary, ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (creatorName != null && creatorName.isNotEmpty) ...[ // const SizedBox(width: 12), Flexible( flex: 1, child: Text( '${l10n.by} $creatorName', maxLines: 1, overflow: TextOverflow.ellipsis, style: mutedStyle?.copyWith( fontStyle: FontStyle.italic, ), ), ), ], const Spacer(), Row( children: [ Icon( Icons.group_outlined, size: 16, color: theme.colorScheme.onSurfaceVariant, ), const SizedBox(width: 2), Text( l10n.countFollowers(followers), style: mutedStyle, ), ], ), ], ), ], ), ), ], ), if (description != null && description.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 8), child: Text( description, maxLines: 3, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), ), ], ), ), ), ), ); } }