diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart index 4f3e69bad1..5773b68dee 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_url_cell.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart'; @@ -177,21 +176,11 @@ class _VisitURLAccessoryState extends State<_VisitURLAccessory> } @override - bool enable() { - return widget.cellDataNotifier.value.isNotEmpty; - } + bool enable() => widget.cellDataNotifier.value.isNotEmpty; @override - void onTap() { - final content = widget.cellDataNotifier.value; - if (content.isEmpty) { - return; - } - final shouldAddScheme = - !['http', 'https'].any((pattern) => content.startsWith(pattern)); - final url = shouldAddScheme ? 'http://$content' : content; - afLaunchUrlString(url); - } + void onTap() => + openUrlCellLink(widget.cellDataNotifier.value); } class _URLAccessoryIconContainer extends StatelessWidget { diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart index 7deb6c85e4..6244c54072 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/editable_cell_skeleton/url.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database/application/database_controller.dart'; @@ -15,6 +16,9 @@ import '../desktop_row_detail/desktop_row_detail_url_cell.dart'; import '../mobile_grid/mobile_grid_url_cell.dart'; import '../mobile_row_detail/mobile_row_detail_url_cell.dart'; +const regexUrl = + r"[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:._\+-~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:_\+.~#?&\/\/=]*)"; + abstract class IEditableURLCellSkin { const IEditableURLCellSkin(); @@ -130,3 +134,24 @@ class _GridURLCellState extends GridEditableTextCell { @override String? onCopy() => cellBloc.state.content; } + +void openUrlCellLink(String content) { + if (RegExp(regexUrl).hasMatch(content)) { + const linkPrefix = [ + 'http://', + 'https://', + 'file://', + 'ftp://', + 'ftps://', + 'mailto:', + ]; + final shouldAddScheme = + !linkPrefix.any((pattern) => content.startsWith(pattern)); + final url = shouldAddScheme ? 'https://$content' : content; + afLaunchUrlString(url); + } else { + afLaunchUrlString( + "https://www.google.com/search?q=${Uri.encodeComponent(content)}", + ); + } +}