feat: Make all text in chat selectable on desktop
This commit is contained in:
parent
7d7e234142
commit
809ee213b6
4 changed files with 222 additions and 194 deletions
|
|
@ -31,7 +31,8 @@ class ChatEventList extends StatelessWidget {
|
|||
thisEventsKeyMap[controller.timeline!.events[i].eventId] = i;
|
||||
}
|
||||
|
||||
return ListView.custom(
|
||||
return SelectionArea(
|
||||
child: ListView.custom(
|
||||
padding: EdgeInsets.only(
|
||||
top: 16,
|
||||
bottom: 4,
|
||||
|
|
@ -130,6 +131,7 @@ class ChatEventList extends StatelessWidget {
|
|||
findChildIndexCallback: (key) =>
|
||||
controller.findChildIndexCallback(key, thisEventsKeyMap),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import 'package:fluffychat/utils/string_color.dart';
|
|||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../../widgets/hover_builder.dart';
|
||||
import 'message_content.dart';
|
||||
import 'message_reactions.dart';
|
||||
import 'reply_content.dart';
|
||||
|
|
@ -44,10 +45,6 @@ class Message extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
/// Indicates wheither the user may use a mouse instead
|
||||
/// of touchscreen.
|
||||
static bool useMouse = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!{
|
||||
|
|
@ -117,15 +114,26 @@ class Message extends StatelessWidget {
|
|||
: Theme.of(context).colorScheme.primaryContainer;
|
||||
}
|
||||
|
||||
final row = Row(
|
||||
final row = InkWell(
|
||||
onTap: longPressSelect ? () => onSelect!(event) : null,
|
||||
onLongPress: () => onSelect!(event),
|
||||
child: HoverBuilder(
|
||||
builder: (context, hovered) => Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: rowMainAxisAlignment,
|
||||
children: [
|
||||
sameSender || ownMessage
|
||||
? SizedBox(
|
||||
if (hovered || selected)
|
||||
SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize - 8,
|
||||
child: Checkbox.adaptive(
|
||||
value: selected,
|
||||
onChanged: (_) => onSelect?.call(event),
|
||||
),
|
||||
)
|
||||
else if (sameSender || ownMessage)
|
||||
SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 16,
|
||||
|
|
@ -139,9 +147,9 @@ class Message extends StatelessWidget {
|
|||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: FutureBuilder<User?>(
|
||||
else
|
||||
FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final user =
|
||||
|
|
@ -205,9 +213,7 @@ class Message extends StatelessWidget {
|
|||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 1.5,
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Column(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
|
|
@ -284,8 +290,6 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -293,6 +297,8 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
Widget container;
|
||||
if (event.hasAggregatedEvents(timeline, RelationshipTypes.reaction) ||
|
||||
|
|
@ -392,12 +398,6 @@ class Message extends StatelessWidget {
|
|||
direction: SwipeDirection.endToStart,
|
||||
onSwipe: onSwipe,
|
||||
child: Center(
|
||||
child: MouseRegion(
|
||||
onEnter: (_) => useMouse = true,
|
||||
onExit: (_) => useMouse = false,
|
||||
child: InkWell(
|
||||
onTap: longPressSelect || useMouse ? () => onSelect!(event) : null,
|
||||
onLongPress: () => onSelect!(event),
|
||||
child: Container(
|
||||
color: selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
|
|
@ -412,8 +412,6 @@ class Message extends StatelessWidget {
|
|||
child: container,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ class CustomScrollBehavior extends MaterialScrollBehavior {
|
|||
@override
|
||||
Set<PointerDeviceKind> get dragDevices => {
|
||||
PointerDeviceKind.touch,
|
||||
PointerDeviceKind.mouse,
|
||||
PointerDeviceKind.trackpad,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
29
lib/widgets/hover_builder.dart
Normal file
29
lib/widgets/hover_builder.dart
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class HoverBuilder extends StatefulWidget {
|
||||
final Widget Function(BuildContext context, bool hovered) builder;
|
||||
const HoverBuilder({required this.builder, super.key});
|
||||
|
||||
@override
|
||||
State<HoverBuilder> createState() => _HoverBuilderState();
|
||||
}
|
||||
|
||||
class _HoverBuilderState extends State<HoverBuilder> {
|
||||
bool hovered = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
onEnter: (_) => hovered
|
||||
? null
|
||||
: setState(() {
|
||||
hovered = true;
|
||||
}),
|
||||
onExit: (_) => !hovered
|
||||
? null
|
||||
: setState(() {
|
||||
hovered = false;
|
||||
}),
|
||||
child: widget.builder(context, hovered),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue