151 lines
5.4 KiB
Dart
151 lines
5.4 KiB
Dart
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import 'package:flutter/material.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.surfaceContainerLow;
|
|
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(
|
|
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
|
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(
|
|
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,
|
|
),
|
|
),
|
|
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 SizedBox(width: 8),
|
|
Icon(
|
|
Icons.group_outlined,
|
|
size: 16,
|
|
color: theme.colorScheme.onSurfaceVariant,
|
|
),
|
|
const SizedBox(width: 4),
|
|
Text(l10n.countFollowers(followers), style: mutedStyle),
|
|
],
|
|
),
|
|
if (description != null && description.isNotEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 8),
|
|
child: Text(
|
|
description,
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: theme.textTheme.bodySmall?.copyWith(
|
|
color: theme.colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|