✨ Message item swipe to
This commit is contained in:
@@ -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),
|
||||||
|
Reference in New Issue
Block a user