Message item swipe to

This commit is contained in:
2025-10-12 17:29:03 +08:00
parent 9d39c6a825
commit 91784e65e6

View File

@@ -25,6 +25,7 @@ import 'package:island/widgets/content/embed/embed_list.dart';
import 'package:island/widgets/post/post_shared.dart'; import 'package:island/widgets/post/post_shared.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:swipe_to/swipe_to.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
class MessageItemAction { class MessageItemAction {
@@ -159,57 +160,79 @@ class MessageItem extends HookConsumerWidget {
return Stack( return Stack(
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
InkWell( SwipeTo(
mouseCursor: MouseCursor.defer, rightSwipeWidget: Transform.flip(
focusColor: Colors.transparent, flipX: true,
onLongPress: showActionMenu, child: Icon(Symbols.menu_open),
onSecondaryTap: showActionMenu, ).padding(left: 16),
onTap: () { leftSwipeWidget: Icon(
// Jump to related message isCurrentUser ? Symbols.forward : Symbols.reply,
if (['messages.update', 'messages.delete'].contains(message.type) && ).padding(right: 16),
message.meta['message_id'] is String && onLeftSwipe: (details) {
message.meta['message_id'] != null) { if (onAction != null) {
onJump(message.meta['message_id']); if (isCurrentUser) {
onAction!(MessageItemAction.forward);
} else {
onAction!(MessageItemAction.reply);
}
} }
}, },
child: SizedBox( onRightSwipe: (details) => showActionMenu(),
width: double.infinity, child: InkWell(
child: MouseRegion( mouseCursor: MouseCursor.defer,
onEnter: (_) => isHovered.value = true, focusColor: Colors.transparent,
onExit: (_) => isHovered.value = false, onLongPress: showActionMenu,
child: AnimatedContainer( onSecondaryTap: showActionMenu,
curve: Curves.easeInOut, onTap: () {
duration: const Duration(milliseconds: kFlashDuration), // Jump to related message
decoration: BoxDecoration(color: flashColor), if ([
child: switch (settings.messageDisplayStyle) { 'messages.update',
'compact' => MessageItemDisplayIRC( 'messages.delete',
message: message, ].contains(message.type) &&
isCurrentUser: isCurrentUser, message.meta['message_id'] is String &&
progress: progress, message.meta['message_id'] != null) {
showAvatar: showAvatar, onJump(message.meta['message_id']);
onJump: onJump, }
translatedText: translatedText.value, },
translating: translating.value, child: SizedBox(
), width: double.infinity,
'column' => MessageItemDisplayDiscord( child: MouseRegion(
message: message, onEnter: (_) => isHovered.value = true,
isCurrentUser: isCurrentUser, onExit: (_) => isHovered.value = false,
progress: progress, child: AnimatedContainer(
showAvatar: showAvatar, curve: Curves.easeInOut,
onJump: onJump, duration: const Duration(milliseconds: kFlashDuration),
translatedText: translatedText.value, decoration: BoxDecoration(color: flashColor),
translating: translating.value, child: switch (settings.messageDisplayStyle) {
), 'compact' => MessageItemDisplayIRC(
_ => MessageItemDisplayBubble( message: message,
message: message, isCurrentUser: isCurrentUser,
isCurrentUser: isCurrentUser, progress: progress,
progress: progress, showAvatar: showAvatar,
showAvatar: showAvatar, onJump: onJump,
onJump: onJump, translatedText: translatedText.value,
translatedText: translatedText.value, translating: translating.value,
translating: translating.value, ),
), 'column' => MessageItemDisplayDiscord(
}, message: message,
isCurrentUser: isCurrentUser,
progress: progress,
showAvatar: showAvatar,
onJump: onJump,
translatedText: translatedText.value,
translating: translating.value,
),
_ => MessageItemDisplayBubble(
message: message,
isCurrentUser: isCurrentUser,
progress: progress,
showAvatar: showAvatar,
onJump: onJump,
translatedText: translatedText.value,
translating: translating.value,
),
},
),
), ),
), ),
), ),
@@ -314,44 +337,47 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// Header // Header
Row( SizedBox(
children: [ height: 24,
Icon( child: Row(
Symbols.article, children: [
size: 16, Icon(
color: Theme.of(context).colorScheme.primary, Symbols.article,
), size: 16,
const Gap(6),
Text(
'messageContent'.tr(),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
), const Gap(6),
const Spacer(), Text(
if (_shouldShowExpandButton) 'messageContent'.tr(),
IconButton( style: TextStyle(
visualDensity: VisualDensity.compact, fontSize: 12,
icon: Icon( fontWeight: FontWeight.w500,
_isExpanded color: Theme.of(context).colorScheme.primary,
? Symbols.expand_less
: Symbols.expand_more,
size: 16,
),
onPressed: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 24,
minHeight: 24,
), ),
), ),
], const Spacer(),
if (_shouldShowExpandButton)
IconButton(
visualDensity: VisualDensity.compact,
icon: Icon(
_isExpanded
? Symbols.expand_less
: Symbols.expand_more,
size: 16,
),
onPressed: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 32,
minHeight: 24,
),
),
],
),
), ),
const Gap(8), const Gap(8),
// Selectable content // Selectable content
@@ -403,7 +429,7 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
Navigator.pop(context); Navigator.pop(context);
}, },
), ),
if (widget.isCurrentUser) const Divider(height: 8), if (widget.isCurrentUser) const Divider(),
_ActionListTile( _ActionListTile(
leading: Icon(Symbols.reply), leading: Icon(Symbols.reply),
@@ -422,7 +448,7 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
}, },
), ),
if (widget.translatableLanguage) const Divider(height: 8), if (widget.translatableLanguage) const Divider(),
if (widget.translatableLanguage) if (widget.translatableLanguage)
_ActionListTile( _ActionListTile(
leading: Icon(Symbols.translate), leading: Icon(Symbols.translate),
@@ -439,7 +465,7 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
}, },
), ),
if (widget.isMobile) const Divider(height: 8), if (widget.isMobile) const Divider(),
if (widget.isMobile) if (widget.isMobile)
_ActionListTile( _ActionListTile(
leading: Icon(Symbols.copy_all), leading: Icon(Symbols.copy_all),