Skip to content

Commit bb50d24

Browse files
fix: 👌 PR Review comments
1 parent a7f4036 commit bb50d24

File tree

5 files changed

+90
-67
lines changed

5 files changed

+90
-67
lines changed

lib/src/models/chat_bubble.dart

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import 'package:flutter/material.dart';
2424

2525
import 'config_models/link_preview_configuration.dart';
2626
import 'config_models/receipts_widget_config.dart';
27+
import 'config_models/text_selection_config.dart';
2728

2829
class ChatBubble {
2930
const ChatBubble({
31+
this.enableTextSelection = true,
3032
this.color,
3133
this.borderRadius,
3234
this.textStyle,
@@ -36,10 +38,8 @@ class ChatBubble {
3638
this.senderNameTextStyle,
3739
this.receiptsWidgetConfig,
3840
this.onMessageRead,
39-
this.isSelectable = true,
4041
this.border,
41-
this.selectionHighlightColor,
42-
this.selectionCursorColor,
42+
this.textSelectionConfig,
4343
});
4444

4545
/// Used for giving color of chat bubble.
@@ -75,11 +75,10 @@ class ChatBubble {
7575
final Border? border;
7676

7777
/// Used to determine whether the text can be selected.
78-
final bool isSelectable;
78+
///
79+
/// Defaults to `true`.
80+
final bool enableTextSelection;
7981

80-
/// Color used to paint the selected text highlight background. If null, falls back to theme.
81-
final Color? selectionHighlightColor;
82-
83-
/// Color for the drag handles. If null, falls back to theme.
84-
final Color? selectionCursorColor;
82+
/// Configuration for text selection behavior and appearance.
83+
final TextSelectionConfig? textSelectionConfig;
8584
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter/rendering.dart';
3+
4+
class TextSelectionConfig {
5+
const TextSelectionConfig({
6+
this.selectionControls,
7+
this.focusNode,
8+
this.onSelectionChanged,
9+
this.contextMenuBuilder,
10+
this.magnifierConfiguration,
11+
this.themeData,
12+
});
13+
14+
/// The delegate to build the selection handles and toolbar.
15+
///
16+
/// If it is null, the platform specific selection control is used.
17+
final TextSelectionControls? selectionControls;
18+
19+
/// {@macro flutter.widgets.Focus.focusNode}
20+
final FocusNode? focusNode;
21+
22+
/// The configuration for the magnifier in the selection region.
23+
///
24+
/// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier]
25+
/// on Android, and builds nothing on all other platforms. To suppress the
26+
/// magnifier, consider passing [TextMagnifierConfiguration.disabled].
27+
///
28+
/// {@macro flutter.widgets.magnifier.intro}
29+
final TextMagnifierConfiguration? magnifierConfiguration;
30+
31+
/// Called when the selected content changes.
32+
final ValueChanged<SelectedContent?>? onSelectionChanged;
33+
34+
/// {@macro flutter.widgets.EditableText.contextMenuBuilder}
35+
///
36+
/// If not provided, will build a default menu based on the ambient
37+
/// [ThemeData.platform].
38+
///
39+
/// {@tool dartpad}
40+
/// This example shows how to build a custom context menu for any selected
41+
/// content in a SelectionArea.
42+
///
43+
/// ** See code in examples/api/lib/material/context_menu/selectable_region_toolbar_builder.0.dart **
44+
/// {@end-tool}
45+
///
46+
/// See also:
47+
///
48+
/// * [AdaptiveTextSelectionToolbar], which is built by default.
49+
final SelectableRegionContextMenuBuilder? contextMenuBuilder;
50+
51+
/// Theme data for text selection.
52+
///
53+
/// If null, defaults to the theme's `TextSelectionThemeData`.
54+
final TextSelectionThemeData? themeData;
55+
}

lib/src/models/models.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export 'config_models/scroll_to_bottom_button_config.dart';
4242
export 'config_models/send_message_configuration.dart';
4343
export 'config_models/suggestion_list_config.dart';
4444
export 'config_models/swipe_to_reply_configuration.dart';
45+
export 'config_models/text_selection_config.dart';
4546
export 'config_models/type_indicator_configuration.dart';
4647
export 'config_models/voice_message_configuration.dart';
4748
export 'overlay_action_widget.dart';
Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:chatview/src/models/config_models/text_selection_config.dart';
12
import 'package:flutter/material.dart';
23

34
/// A convenience wrapper around [SelectionArea] that lets you locally
@@ -6,66 +7,39 @@ import 'package:flutter/material.dart';
67
78
class CustomSelectionArea extends StatelessWidget {
89
const CustomSelectionArea({
9-
super.key,
1010
required this.child,
11-
this.selectionColor,
12-
this.selectionHandleColor,
13-
this.selectionControls,
14-
this.cursorColor,
11+
this.config,
12+
super.key,
1513
});
1614

1715
/// The subtree whose text becomes selectable.
1816
final Widget child;
1917

20-
/// Color used to paint the selected text highlight background.
21-
final Color? selectionColor;
22-
23-
/// Color for the drag handles. If null, falls back to theme.
24-
final Color? selectionHandleColor;
25-
26-
/// Optional custom selection controls (toolbar / handles). If you just need
27-
/// color tweaks, you usually do not need to supply this.
28-
final TextSelectionControls? selectionControls;
29-
30-
/// Cursor color for any text.
31-
final Color? cursorColor;
18+
/// Configuration for text selection behavior and appearance.
19+
final TextSelectionConfig? config;
3220

3321
@override
3422
Widget build(BuildContext context) {
35-
final theme = Theme.of(context);
36-
final baseTextSelectionTheme = theme.textSelectionTheme;
37-
38-
final mergedTextSelectionTheme = baseTextSelectionTheme.copyWith(
39-
selectionColor: selectionColor ?? baseTextSelectionTheme.selectionColor,
40-
selectionHandleColor:
41-
selectionHandleColor ?? baseTextSelectionTheme.selectionHandleColor,
42-
cursorColor: cursorColor ?? baseTextSelectionTheme.cursorColor,
43-
);
44-
4523
return Theme(
46-
data: theme.copyWith(textSelectionTheme: mergedTextSelectionTheme),
47-
child: SelectionArea(selectionControls: selectionControls, child: child),
24+
data: Theme.of(context).copyWith(textSelectionTheme: config?.themeData),
25+
child: SelectionArea(
26+
focusNode: config?.focusNode,
27+
selectionControls: config?.selectionControls,
28+
contextMenuBuilder:
29+
config?.contextMenuBuilder ?? _defaultContextMenuBuilder,
30+
onSelectionChanged: config?.onSelectionChanged,
31+
magnifierConfiguration: config?.magnifierConfiguration,
32+
child: child,
33+
),
4834
);
4935
}
50-
}
5136

52-
class ColoredTextSelectionControls extends MaterialTextSelectionControls {
53-
ColoredTextSelectionControls(this.handleColor);
54-
55-
/// Color for the drag handles.
56-
final Color handleColor;
57-
58-
@override
59-
Widget buildHandle(
37+
static Widget _defaultContextMenuBuilder(
6038
BuildContext context,
61-
TextSelectionHandleType type,
62-
double textHeight, [
63-
VoidCallback? onTap,
64-
]) {
65-
final handle = super.buildHandle(context, type, textHeight, onTap);
66-
return IconTheme.merge(
67-
data: IconThemeData(color: handleColor),
68-
child: handle,
39+
SelectableRegionState selectableRegionState,
40+
) {
41+
return AdaptiveTextSelectionToolbar.selectableRegion(
42+
selectableRegionState: selectableRegionState,
6943
);
7044
}
7145
}

lib/src/widgets/text_message_view.dart

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,11 @@ class TextMessageView extends StatelessWidget {
7676
? outgoingChatBubbleConfig?.border
7777
: inComingChatBubbleConfig?.border;
7878
final isSelectable = isMessageBySender
79-
? outgoingChatBubbleConfig?.isSelectable ?? false
80-
: inComingChatBubbleConfig?.isSelectable ?? false;
81-
final selectionHighlightColor = isMessageBySender
82-
? outgoingChatBubbleConfig?.selectionHighlightColor
83-
: inComingChatBubbleConfig?.selectionHighlightColor;
84-
final selectionCursorColor = isMessageBySender
85-
? outgoingChatBubbleConfig?.selectionCursorColor
86-
: inComingChatBubbleConfig?.selectionCursorColor;
79+
? outgoingChatBubbleConfig?.enableTextSelection ?? false
80+
: inComingChatBubbleConfig?.enableTextSelection ?? false;
81+
final textSelectionConfig = isMessageBySender
82+
? outgoingChatBubbleConfig?.textSelectionConfig
83+
: inComingChatBubbleConfig?.textSelectionConfig;
8784
final baseWidget = Text(
8885
textMessage,
8986
style: _textStyle ??
@@ -119,10 +116,7 @@ class TextMessageView extends StatelessWidget {
119116
)
120117
: isSelectable
121118
? CustomSelectionArea(
122-
selectionColor: selectionHighlightColor,
123-
selectionHandleColor: selectionCursorColor,
124-
selectionControls: ColoredTextSelectionControls(
125-
selectionCursorColor ?? Colors.black),
119+
config: textSelectionConfig,
126120
child: baseWidget,
127121
)
128122
: baseWidget,

0 commit comments

Comments
 (0)