Skip to content

Commit

Permalink
TW-2114: Add context menu when click on phone number on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
nqhhdev committed Nov 13, 2024
1 parent af677f6 commit ef55e94
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 32 deletions.
3 changes: 2 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -3096,5 +3096,6 @@
"enable_notifications": "Enable notifications",
"disable_notifications": "Disable notifications",
"logoutDialogWarning": "You will lose access to encrypted messages. We recommend that you enable chat backups before logging out",
"copyNumber": "Copy number"
"copyNumber": "Copy number",
"callViaCarrier": "Call via Carrier"
}
6 changes: 1 addition & 5 deletions lib/pages/chat/chat_context_menu_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ enum ChatContextMenuActions {
pinChat,
forward,
downloadFile,
jumpToMessage,
copyNumber;
jumpToMessage;

String getTitle(
BuildContext context, {
Expand All @@ -31,8 +30,6 @@ enum ChatContextMenuActions {
return L10n.of(context)!.download;
case ChatContextMenuActions.jumpToMessage:
return L10n.of(context)!.jumpToMessage;
case ChatContextMenuActions.copyNumber:
return L10n.of(context)!.copyNumber;
}
}

Expand All @@ -44,7 +41,6 @@ enum ChatContextMenuActions {
case ChatContextMenuActions.select:
return isSelected ? Icons.circle_outlined : Icons.check_circle_outline;
case ChatContextMenuActions.copyMessage:
case ChatContextMenuActions.copyNumber:
return Icons.content_copy;
case ChatContextMenuActions.pinChat:
return !unpin ? Icons.push_pin_outlined : null;
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/chat/events/html_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class HtmlMessage extends StatelessWidget with LinkifyMixin {
],
shrinkToFit: true,
maxLines: maxLines,
onLinkTap: (tapDownDetails, link) => handleOnTappedLinkHtml(
onTapDownLink: (tapDownDetails, link) => handleOnTappedLinkHtml(
context: context,
details: tapDownDetails,
link: link,
Expand Down
25 changes: 25 additions & 0 deletions lib/pages/chat/phone_number_context_menu_actions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';

enum PhoneNumberContextMenuActions {
call,
copy;

String getTitle(BuildContext context) {
switch (this) {
case PhoneNumberContextMenuActions.call:
return L10n.of(context)!.callViaCarrier;
case PhoneNumberContextMenuActions.copy:
return L10n.of(context)!.copyNumber;
}
}

IconData getIconData() {
switch (this) {
case PhoneNumberContextMenuActions.call:
return Icons.call_outlined;
case PhoneNumberContextMenuActions.copy:
return Icons.content_copy_outlined;
}
}
}
91 changes: 77 additions & 14 deletions lib/presentation/mixins/linkify_mixin.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import 'package:fluffychat/pages/chat/chat_context_menu_actions.dart';
import 'package:fluffychat/pages/chat/phone_number_context_menu_actions.dart';
import 'package:fluffychat/utils/extension/build_context_extension.dart';
import 'package:fluffychat/utils/extension/value_notifier_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/context_menu/context_menu_action.dart';
import 'package:fluffychat/widgets/context_menu/twake_context_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter/services.dart';
import 'package:linagora_design_flutter/linagora_design_flutter.dart';
import 'package:linkfy_text/linkfy_text.dart';
import 'package:matrix/matrix.dart';
import 'package:pull_down_button/pull_down_button.dart';
import 'package:url_launcher/url_launcher.dart';

mixin LinkifyMixin {
final ValueNotifier<bool> openingPopupMenu = ValueNotifier(false);

List<ChatContextMenuActions> get phoneNumberContextMenu => [
ChatContextMenuActions.copyNumber,
List<PhoneNumberContextMenuActions> get phoneNumberContextMenuOnWeb => [
PhoneNumberContextMenuActions.copy,
];

List<ContextMenuAction> _mapPopupMenuActionsToContextMenuActions({
required BuildContext context,
required List<ChatContextMenuActions> actions,
required List<PhoneNumberContextMenuActions> actions,
}) {
return actions.map((action) {
return ContextMenuAction(
Expand All @@ -41,7 +47,7 @@ mixin LinkifyMixin {
final offset = tapDownDetails.globalPosition;
final listActions = _mapPopupMenuActionsToContextMenuActions(
context: context,
actions: phoneNumberContextMenu,
actions: phoneNumberContextMenuOnWeb,
);
final selectedActionIndex = await showTwakeContextMenu(
context: context,
Expand All @@ -51,7 +57,7 @@ mixin LinkifyMixin {
);
if (selectedActionIndex != null && selectedActionIndex is int) {
_handleClickOnContextMenuItem(
action: phoneNumberContextMenu[selectedActionIndex],
action: phoneNumberContextMenuOnWeb[selectedActionIndex],
number: number,
);
}
Expand Down Expand Up @@ -83,11 +89,11 @@ mixin LinkifyMixin {
}

void _handleClickOnContextMenuItem({
required ChatContextMenuActions action,
required PhoneNumberContextMenuActions action,
required String number,
}) async {
switch (action) {
case ChatContextMenuActions.copyNumber:
case PhoneNumberContextMenuActions.copy:
Logs().i('LinkifyMixin: handleContextMenuAction: copyNumber $number');
await Clipboard.setData(ClipboardData(text: number));
break;
Expand All @@ -96,11 +102,60 @@ mixin LinkifyMixin {
}
}

Future<void> _handleShowPullDownMenu({
required BuildContext context,
required TapDownDetails tapDownDetails,
required String number,
}) {
return showPullDownMenu(
context: context,
items: [
PullDownMenuItem(
onTap: () async {
final phoneUri = Uri(
scheme: "tel",
path: number.replaceAll(' ', ''),
);
if (await canLaunchUrl(phoneUri)) {
launchUrl(phoneUri);
} else {
Logs().e(
'LinkifyMixin: handleOnTappedLink: Cannot launch phoneUri: $phoneUri',
);
}
},
title: L10n.of(context)!.callViaCarrier,
icon: Icons.call_outlined,
),
PullDownMenuItem(
title: L10n.of(context)!.copyNumber,
onTap: () async {
await Clipboard.setData(
ClipboardData(text: number),
);
},
icon: Icons.content_copy_outlined,
),
const PullDownMenuDivider.large(),
PullDownMenuItem(
title: number,
onTap: () {},
itemTheme: PullDownMenuItemTheme(
textStyle: context.textTheme.bodyLarge!.copyWith(
color: LinagoraRefColors.material().neutral[30],
),
),
),
],
position: tapDownDetails.globalPosition & Size.zero,
);
}

void handleOnTappedLinkHtml({
required BuildContext context,
required TapDownDetails details,
required Link link,
}) {
}) async {
Logs().i(
'LinkifyMixin: handleOnTappedLink: type: ${link.type} link: ${link.value}',
);
Expand All @@ -109,11 +164,19 @@ mixin LinkifyMixin {
UrlLauncher(context, url: link.value.toString()).launchUrl();
break;
case LinkType.phone:
_handleContextMenuAction(
context: context,
tapDownDetails: details,
number: link.value.toString(),
);
if (PlatformInfos.isMobile) {
_handleShowPullDownMenu(
context: context,
tapDownDetails: details,
number: link.value.toString(),
);
} else {
_handleContextMenuAction(
context: context,
tapDownDetails: details,
number: link.value.toString(),
);
}
break;
default:
Logs().i('LinkifyMixin: handleOnTappedLink: Unhandled link: $link');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,16 @@ class TwakeLinkPreviewController extends State<TwakeLinkPreview>
linkStyle: widget.linkStyle,
fontSize: widget.fontSize,
)
: LinkifyText(
widget.localizedBody,
: MatrixLinkifyText(
text: widget.localizedBody,
textStyle: widget.richTextStyle,
linkStyle: widget.linkStyle,
linkTypes: const [
LinkType.url,
LinkType.phone,
],
textAlign: TextAlign.start,
onLinkTap: (tapDownDetails, link) => handleOnTappedLinkHtml(
onTapDownLink: (tapDownDetails, link) => handleOnTappedLinkHtml(
context: context,
details: tapDownDetails,
link: link,
Expand Down
18 changes: 13 additions & 5 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1168,8 +1168,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: implement-linkify-text
resolved-ref: "7884a5fa64cbd40f3997c4071bbbdc67049c17ae"
ref: master
resolved-ref: "1cb28dfcc9536e200b3f74ab1c5d48386b8524d3"
url: "https://github.com/linagora/flutter_matrix_html.git"
source: git
version: "1.2.0"
Expand Down Expand Up @@ -1795,9 +1795,9 @@ packages:
dependency: "direct main"
description:
path: "."
ref: refactor-linkify
resolved-ref: b4a418e454ef48c60829d6840b1778f03302f8bf
url: "[email protected]:nqhhdev/linkfy_text.git"
ref: main
resolved-ref: "6690e87f19e024d70b68efbc70d2159c34b5d0fc"
url: "[email protected]:linagora/linkfy_text.git"
source: git
version: "1.1.6"
lints:
Expand Down Expand Up @@ -2372,6 +2372,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.3"
pull_down_button:
dependency: "direct main"
description:
name: pull_down_button
sha256: "12cdd8ff187a3150ebdf075e5074299f085579b158d2b4e655ccbafccf95f25b"
url: "https://pub.dev"
source: hosted
version: "0.10.2"
punycode:
dependency: "direct main"
description:
Expand Down
7 changes: 4 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ dependencies:
flutter_matrix_html:
git:
url: https://github.com/linagora/flutter_matrix_html.git
ref: implement-linkify-text
ref: master

contacts_service:
git:
Expand Down Expand Up @@ -62,8 +62,8 @@ dependencies:

linkfy_text:
git:
url: [email protected]:nqhhdev/linkfy_text.git
ref: refactor-linkify
url: [email protected]:linagora/linkfy_text.git
ref: main

adaptive_dialog: ^1.8.0+1
flutter_adaptive_scaffold: ^0.1.4
Expand Down Expand Up @@ -211,6 +211,7 @@ dependencies:
auto_size_text: 3.0.0
flutter_avif: 2.4.1
heif_converter: 1.0.0
pull_down_button: 0.10.2

dev_dependencies:
build_runner: 2.4.12
Expand Down

0 comments on commit ef55e94

Please sign in to comment.