chore: Follow up new reactions picker
This commit is contained in:
parent
37d313c271
commit
13f27eda9f
5 changed files with 488 additions and 354 deletions
|
|
@ -24,7 +24,7 @@ abstract class AppConfig {
|
||||||
static String _privacyUrl =
|
static String _privacyUrl =
|
||||||
'https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md';
|
'https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md';
|
||||||
|
|
||||||
static const Set<String> defaultReactions = {'👍', '❤️', '😊'};
|
static const Set<String> defaultReactions = {'👍', '❤️', '😂', '😮', '😢'};
|
||||||
|
|
||||||
static String get privacyUrl => _privacyUrl;
|
static String get privacyUrl => _privacyUrl;
|
||||||
static const String website = 'https://fluffychat.im';
|
static const String website = 'https://fluffychat.im';
|
||||||
|
|
|
||||||
|
|
@ -891,6 +891,16 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get canEditSelectedEvents {
|
||||||
|
if (isArchived ||
|
||||||
|
selectedEvents.length != 1 ||
|
||||||
|
!selectedEvents.first.status.isSent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return currentRoomBundle
|
||||||
|
.any((cl) => selectedEvents.first.senderId == cl!.userID);
|
||||||
|
}
|
||||||
|
|
||||||
void forwardEventsAction() async {
|
void forwardEventsAction() async {
|
||||||
if (selectedEvents.isEmpty) return;
|
if (selectedEvents.isEmpty) return;
|
||||||
await showScaffoldDialog(
|
await showScaffoldDialog(
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
const height = 48.0;
|
const height = 48.0;
|
||||||
|
|
||||||
if (!controller.room.otherPartyCanReceiveMessages) {
|
if (!controller.room.otherPartyCanReceiveMessages) {
|
||||||
|
|
@ -39,7 +40,71 @@ class ChatInputRow extends StatelessWidget {
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: controller.selectMode
|
||||||
|
? <Widget>[
|
||||||
|
if (controller.selectedEvents
|
||||||
|
.every((event) => event.status == EventStatus.error))
|
||||||
|
SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: theme.colorScheme.error,
|
||||||
|
),
|
||||||
|
onPressed: controller.deleteErrorEventsAction,
|
||||||
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
const Icon(Icons.delete),
|
||||||
|
Text(L10n.of(context).delete),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: controller.forwardEventsAction,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
const Icon(Icons.keyboard_arrow_left_outlined),
|
||||||
|
Text(L10n.of(context).forward),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller.selectedEvents.length == 1
|
||||||
|
? controller.selectedEvents.first
|
||||||
|
.getDisplayEvent(controller.timeline!)
|
||||||
|
.status
|
||||||
|
.isSent
|
||||||
|
? SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: controller.replyAction,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Text(L10n.of(context).reply),
|
||||||
|
const Icon(Icons.keyboard_arrow_right),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: controller.sendAgainAction,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Text(L10n.of(context).tryToSendAgain),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
const Icon(Icons.send_outlined, size: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
]
|
||||||
|
: <Widget>[
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
|
|
@ -51,17 +116,18 @@ class ChatInputRow extends StatelessWidget {
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: PopupMenuButton<String>(
|
child: PopupMenuButton<String>(
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
enabled: !controller.selectMode,
|
|
||||||
icon: const Icon(Icons.add_circle_outline),
|
icon: const Icon(Icons.add_circle_outline),
|
||||||
iconColor: theme.colorScheme.onPrimaryContainer,
|
iconColor: theme.colorScheme.onPrimaryContainer,
|
||||||
onSelected: controller.onAddPopupMenuButtonSelected,
|
onSelected: controller.onAddPopupMenuButtonSelected,
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
itemBuilder: (BuildContext context) =>
|
||||||
|
<PopupMenuEntry<String>>[
|
||||||
if (PlatformInfos.isMobile)
|
if (PlatformInfos.isMobile)
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: 'location',
|
value: 'location',
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: theme.colorScheme.onPrimaryContainer,
|
backgroundColor:
|
||||||
|
theme.colorScheme.onPrimaryContainer,
|
||||||
foregroundColor: theme.colorScheme.primaryContainer,
|
foregroundColor: theme.colorScheme.primaryContainer,
|
||||||
child: const Icon(Icons.gps_fixed_outlined),
|
child: const Icon(Icons.gps_fixed_outlined),
|
||||||
),
|
),
|
||||||
|
|
@ -118,7 +184,6 @@ class ChatInputRow extends StatelessWidget {
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: PopupMenuButton(
|
child: PopupMenuButton(
|
||||||
enabled: !controller.selectMode,
|
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
icon: const Icon(Icons.camera_alt_outlined),
|
icon: const Icon(Icons.camera_alt_outlined),
|
||||||
onSelected: controller.onAddPopupMenuButtonSelected,
|
onSelected: controller.onAddPopupMenuButtonSelected,
|
||||||
|
|
@ -128,7 +193,8 @@ class ChatInputRow extends StatelessWidget {
|
||||||
value: 'camera-video',
|
value: 'camera-video',
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: theme.colorScheme.onPrimaryContainer,
|
backgroundColor:
|
||||||
|
theme.colorScheme.onPrimaryContainer,
|
||||||
foregroundColor: theme.colorScheme.primaryContainer,
|
foregroundColor: theme.colorScheme.primaryContainer,
|
||||||
child: const Icon(Icons.videocam_outlined),
|
child: const Icon(Icons.videocam_outlined),
|
||||||
),
|
),
|
||||||
|
|
@ -140,7 +206,8 @@ class ChatInputRow extends StatelessWidget {
|
||||||
value: 'camera',
|
value: 'camera',
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: theme.colorScheme.onPrimaryContainer,
|
backgroundColor:
|
||||||
|
theme.colorScheme.onPrimaryContainer,
|
||||||
foregroundColor: theme.colorScheme.primaryContainer,
|
foregroundColor: theme.colorScheme.primaryContainer,
|
||||||
child: const Icon(Icons.camera_alt_outlined),
|
child: const Icon(Icons.camera_alt_outlined),
|
||||||
),
|
),
|
||||||
|
|
@ -179,8 +246,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
key: ValueKey(controller.showEmojiPicker),
|
key: ValueKey(controller.showEmojiPicker),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed:
|
onPressed: controller.emojiPickerAction,
|
||||||
controller.selectMode ? null : controller.emojiPickerAction,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (Matrix.of(context).isMultiAccount &&
|
if (Matrix.of(context).isMultiAccount &&
|
||||||
|
|
@ -198,7 +264,6 @@ class ChatInputRow extends StatelessWidget {
|
||||||
child: InputBar(
|
child: InputBar(
|
||||||
room: controller.room,
|
room: controller.room,
|
||||||
minLines: 1,
|
minLines: 1,
|
||||||
readOnly: controller.selectMode,
|
|
||||||
maxLines: 8,
|
maxLines: 8,
|
||||||
autofocus: !PlatformInfos.isMobile,
|
autofocus: !PlatformInfos.isMobile,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
|
|
@ -227,9 +292,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Opacity(
|
Container(
|
||||||
opacity: controller.selectMode ? 0.66 : 1,
|
|
||||||
child: Container(
|
|
||||||
height: height,
|
height: height,
|
||||||
width: height,
|
width: height,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
@ -237,9 +300,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
controller.sendController.text.isEmpty
|
controller.sendController.text.isEmpty
|
||||||
? FloatingActionButton.small(
|
? FloatingActionButton.small(
|
||||||
tooltip: L10n.of(context).voiceMessage,
|
tooltip: L10n.of(context).voiceMessage,
|
||||||
onPressed: controller.selectMode
|
onPressed: controller.voiceMessageAction,
|
||||||
? null
|
|
||||||
: controller.voiceMessageAction,
|
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
heroTag: null,
|
heroTag: null,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
|
|
@ -251,7 +312,7 @@ class ChatInputRow extends StatelessWidget {
|
||||||
)
|
)
|
||||||
: FloatingActionButton.small(
|
: FloatingActionButton.small(
|
||||||
tooltip: L10n.of(context).send,
|
tooltip: L10n.of(context).send,
|
||||||
onPressed: controller.selectMode ? null : controller.send,
|
onPressed: controller.send,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
heroTag: null,
|
heroTag: null,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
|
|
@ -262,7 +323,6 @@ class ChatInputRow extends StatelessWidget {
|
||||||
child: const Icon(Icons.send_outlined),
|
child: const Icon(Icons.send_outlined),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,12 @@ class ChatView extends StatelessWidget {
|
||||||
List<Widget> _appBarActions(BuildContext context) {
|
List<Widget> _appBarActions(BuildContext context) {
|
||||||
if (controller.selectMode) {
|
if (controller.selectMode) {
|
||||||
return [
|
return [
|
||||||
|
if (controller.canEditSelectedEvents)
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit_outlined),
|
||||||
|
tooltip: L10n.of(context).edit,
|
||||||
|
onPressed: controller.editSelectedEventAction,
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.copy_outlined),
|
icon: const Icon(Icons.copy_outlined),
|
||||||
tooltip: L10n.of(context).copy,
|
tooltip: L10n.of(context).copy,
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,9 @@ class Message extends StatelessWidget {
|
||||||
final showReceiptsRow =
|
final showReceiptsRow =
|
||||||
event.hasAggregatedEvents(timeline, RelationshipTypes.reaction);
|
event.hasAggregatedEvents(timeline, RelationshipTypes.reaction);
|
||||||
|
|
||||||
|
final showReactionPicker =
|
||||||
|
singleSelected && event.room.canSendDefaultMessages;
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: Swipeable(
|
child: Swipeable(
|
||||||
key: ValueKey(event.eventId),
|
key: ValueKey(event.eventId),
|
||||||
|
|
@ -263,6 +266,7 @@ class Message extends StatelessWidget {
|
||||||
child: animateIn
|
child: animateIn
|
||||||
? const SizedBox(height: 0, width: double.infinity)
|
? const SizedBox(height: 0, width: double.infinity)
|
||||||
: Stack(
|
: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
|
|
@ -290,7 +294,7 @@ class Message extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: rowMainAxisAlignment,
|
mainAxisAlignment: rowMainAxisAlignment,
|
||||||
children: [
|
children: [
|
||||||
if (longPressSelect)
|
if (longPressSelect && !event.redacted)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 32,
|
height: 32,
|
||||||
width: Avatar.defaultSize,
|
width: Avatar.defaultSize,
|
||||||
|
|
@ -413,8 +417,10 @@ class Message extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
alignment: alignment,
|
alignment: alignment,
|
||||||
padding:
|
padding: EdgeInsets.only(
|
||||||
const EdgeInsets.only(left: 8),
|
left: 8,
|
||||||
|
bottom: showReactionPicker ? 40 : 0,
|
||||||
|
),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onLongPress: longPressSelect
|
onLongPress: longPressSelect
|
||||||
? null
|
? null
|
||||||
|
|
@ -625,75 +631,125 @@ class Message extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
Positioned(
|
||||||
),
|
left:
|
||||||
);
|
ownMessage ? null : Avatar.defaultSize + 8,
|
||||||
},
|
right: ownMessage ? 0 : null,
|
||||||
),
|
bottom: 0,
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: Avatar.defaultSize + 8.0),
|
|
||||||
child: AnimatedSize(
|
child: AnimatedSize(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
curve: FluffyThemes.animationCurve,
|
curve: FluffyThemes.animationCurve,
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: singleSelected && event.room.canSendDefaultMessages
|
child: showReactionPicker
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 4.0),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 8.0,
|
||||||
|
bottom: 4.0,
|
||||||
|
),
|
||||||
child: Material(
|
child: Material(
|
||||||
elevation: 4,
|
elevation: 4,
|
||||||
borderRadius:
|
borderRadius: BorderRadius.circular(
|
||||||
BorderRadius.circular(AppConfig.borderRadius),
|
AppConfig.borderRadius,
|
||||||
shadowColor: theme.appBarTheme.shadowColor,
|
),
|
||||||
|
shadowColor: theme
|
||||||
|
.colorScheme.surface
|
||||||
|
.withAlpha(128),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
...AppConfig.defaultReactions
|
||||||
icon: const Icon(Icons.reply_outlined),
|
.map(
|
||||||
tooltip: L10n.of(context).reply,
|
(emoji) => IconButton(
|
||||||
onPressed: onSwipe,
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Center(
|
||||||
|
child: Opacity(
|
||||||
|
opacity: sentReactions
|
||||||
|
.contains(emoji)
|
||||||
|
? 0.33
|
||||||
|
: 1,
|
||||||
|
child: Text(
|
||||||
|
emoji,
|
||||||
|
style:
|
||||||
|
const TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
textAlign:
|
||||||
|
TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: sentReactions
|
||||||
|
.contains(emoji)
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
onSelect(event);
|
||||||
|
event.room
|
||||||
|
.sendReaction(
|
||||||
|
event.eventId,
|
||||||
|
emoji,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
if (ownMessage)
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.edit_outlined),
|
|
||||||
tooltip: L10n.of(context).edit,
|
|
||||||
onPressed: onEdit,
|
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.add_reaction_outlined),
|
icon: const Icon(
|
||||||
tooltip: L10n.of(context).customReaction,
|
Icons.add_reaction_outlined,
|
||||||
|
),
|
||||||
|
tooltip: L10n.of(context)
|
||||||
|
.customReaction,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final emoji = await showDialog<String>(
|
final emoji =
|
||||||
|
await showDialog<
|
||||||
|
String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) =>
|
||||||
|
AlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize:
|
||||||
|
MainAxisSize.min,
|
||||||
spacing: 4,
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
CloseButton(
|
CloseButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
Navigator.of(context)
|
Navigator.of(
|
||||||
.pop(null),
|
context,
|
||||||
|
).pop(
|
||||||
|
null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
L10n.of(context).customReaction,
|
L10n.of(context)
|
||||||
|
.customReaction,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
titlePadding: const EdgeInsets.all(8),
|
titlePadding:
|
||||||
contentPadding: const EdgeInsets.all(0),
|
const EdgeInsets
|
||||||
clipBehavior: Clip.hardEdge,
|
.all(8),
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets
|
||||||
|
.all(0),
|
||||||
|
clipBehavior:
|
||||||
|
Clip.hardEdge,
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
width: 350,
|
width: 350,
|
||||||
height: 350,
|
height: 350,
|
||||||
child: EmojiPicker(
|
child: EmojiPicker(
|
||||||
onEmojiSelected: (_, emoji) =>
|
onEmojiSelected: (
|
||||||
Navigator.of(context)
|
_,
|
||||||
.pop(emoji.emoji),
|
emoji,
|
||||||
|
) =>
|
||||||
|
Navigator.of(
|
||||||
|
context,
|
||||||
|
).pop(
|
||||||
|
emoji.emoji,
|
||||||
|
),
|
||||||
config: Config(
|
config: Config(
|
||||||
emojiViewConfig:
|
emojiViewConfig:
|
||||||
const EmojiViewConfig(
|
const EmojiViewConfig(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
Colors.transparent,
|
Colors
|
||||||
|
.transparent,
|
||||||
),
|
),
|
||||||
bottomActionBarConfig:
|
bottomActionBarConfig:
|
||||||
const BottomActionBarConfig(
|
const BottomActionBarConfig(
|
||||||
|
|
@ -701,29 +757,45 @@ class Message extends StatelessWidget {
|
||||||
),
|
),
|
||||||
categoryViewConfig:
|
categoryViewConfig:
|
||||||
CategoryViewConfig(
|
CategoryViewConfig(
|
||||||
initCategory: Category.SMILEYS,
|
initCategory:
|
||||||
backspaceColor:
|
Category
|
||||||
theme.colorScheme.primary,
|
.SMILEYS,
|
||||||
|
backspaceColor: theme
|
||||||
|
.colorScheme
|
||||||
|
.primary,
|
||||||
iconColor: theme
|
iconColor: theme
|
||||||
.colorScheme.primary
|
.colorScheme
|
||||||
.withAlpha(128),
|
.primary
|
||||||
iconColorSelected:
|
.withAlpha(
|
||||||
theme.colorScheme.primary,
|
128,
|
||||||
indicatorColor:
|
|
||||||
theme.colorScheme.primary,
|
|
||||||
backgroundColor:
|
|
||||||
theme.colorScheme.surface,
|
|
||||||
),
|
),
|
||||||
skinToneConfig: SkinToneConfig(
|
iconColorSelected:
|
||||||
|
theme
|
||||||
|
.colorScheme
|
||||||
|
.primary,
|
||||||
|
indicatorColor: theme
|
||||||
|
.colorScheme
|
||||||
|
.primary,
|
||||||
|
backgroundColor:
|
||||||
|
theme
|
||||||
|
.colorScheme
|
||||||
|
.surface,
|
||||||
|
),
|
||||||
|
skinToneConfig:
|
||||||
|
SkinToneConfig(
|
||||||
dialogBackgroundColor:
|
dialogBackgroundColor:
|
||||||
Color.lerp(
|
Color.lerp(
|
||||||
theme.colorScheme.surface,
|
theme
|
||||||
theme.colorScheme
|
.colorScheme
|
||||||
|
.surface,
|
||||||
|
theme
|
||||||
|
.colorScheme
|
||||||
.primaryContainer,
|
.primaryContainer,
|
||||||
0.75,
|
0.75,
|
||||||
)!,
|
)!,
|
||||||
indicatorColor:
|
indicatorColor: theme
|
||||||
theme.colorScheme.onSurface,
|
.colorScheme
|
||||||
|
.onSurface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -731,40 +803,20 @@ class Message extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (emoji == null) return;
|
if (emoji == null) return;
|
||||||
if (sentReactions.contains(emoji)) return;
|
if (sentReactions.contains(
|
||||||
|
|
||||||
await event.room.sendReaction(
|
|
||||||
event.eventId,
|
|
||||||
emoji,
|
emoji,
|
||||||
);
|
)) {
|
||||||
},
|
return;
|
||||||
),
|
}
|
||||||
...AppConfig.defaultReactions.map(
|
|
||||||
(emoji) => IconButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
icon: Center(
|
|
||||||
child: Opacity(
|
|
||||||
opacity: sentReactions.contains(emoji)
|
|
||||||
? 0.33
|
|
||||||
: 1,
|
|
||||||
child: Text(
|
|
||||||
emoji,
|
|
||||||
style: const TextStyle(fontSize: 20),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: sentReactions.contains(emoji)
|
|
||||||
? null
|
|
||||||
: () {
|
|
||||||
onSelect(event);
|
onSelect(event);
|
||||||
event.room.sendReaction(
|
|
||||||
|
await event.room
|
||||||
|
.sendReaction(
|
||||||
event.eventId,
|
event.eventId,
|
||||||
emoji,
|
emoji,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -772,9 +824,15 @@ class Message extends StatelessWidget {
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
AnimatedSize(
|
AnimatedSize(
|
||||||
duration: FluffyThemes.animationDuration,
|
duration: FluffyThemes.animationDuration,
|
||||||
curve: FluffyThemes.animationCurve,
|
curve: FluffyThemes.animationCurve,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
child: !showReceiptsRow
|
child: !showReceiptsRow
|
||||||
? const SizedBox.shrink()
|
? const SizedBox.shrink()
|
||||||
: Padding(
|
: Padding(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue