dartlangeditorflutterflutter-appsflutter-examplesflutter-packageflutter-widgetquillquill-deltaquilljsreactquillrich-textrich-text-editorwysiwygwysiwyg-editor
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
4.4 KiB
171 lines
4.4 KiB
import 'package:flutter/cupertino.dart'; |
|
import 'package:flutter/foundation.dart'; |
|
import 'package:flutter/material.dart'; |
|
|
|
import '../models/documents/nodes/node.dart'; |
|
import '../translations/toolbar.i18n.dart'; |
|
|
|
/// List of possible actions returned from [LinkActionPickerDelegate]. |
|
enum LinkMenuAction { |
|
/// Launch the link |
|
launch, |
|
|
|
/// Copy to clipboard |
|
copy, |
|
|
|
/// Remove link style attribute |
|
remove, |
|
|
|
/// No-op |
|
none, |
|
} |
|
|
|
/// Used internally by widget layer. |
|
typedef LinkActionPicker = Future<LinkMenuAction> Function(Node linkNode); |
|
|
|
typedef LinkActionPickerDelegate = Future<LinkMenuAction> Function( |
|
BuildContext context, String link); |
|
|
|
Future<LinkMenuAction> defaultLinkActionPickerDelegate( |
|
BuildContext context, String link) async { |
|
switch (defaultTargetPlatform) { |
|
case TargetPlatform.iOS: |
|
return _showCupertinoLinkMenu(context, link); |
|
case TargetPlatform.android: |
|
return _showMaterialMenu(context, link); |
|
default: |
|
assert( |
|
false, |
|
'defaultShowLinkActionsMenu not supposed to ' |
|
'be invoked for $defaultTargetPlatform'); |
|
return LinkMenuAction.none; |
|
} |
|
} |
|
|
|
Future<LinkMenuAction> _showCupertinoLinkMenu( |
|
BuildContext context, String link) async { |
|
final result = await showCupertinoModalPopup<LinkMenuAction>( |
|
context: context, |
|
builder: (ctx) { |
|
return CupertinoActionSheet( |
|
title: Text(link), |
|
actions: [ |
|
_CupertinoAction( |
|
title: 'Open', |
|
icon: Icons.language_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.launch), |
|
), |
|
_CupertinoAction( |
|
title: 'Copy', |
|
icon: Icons.copy_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.copy), |
|
), |
|
_CupertinoAction( |
|
title: 'Remove', |
|
icon: Icons.link_off_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.remove), |
|
), |
|
], |
|
); |
|
}, |
|
); |
|
return result ?? LinkMenuAction.none; |
|
} |
|
|
|
class _CupertinoAction extends StatelessWidget { |
|
const _CupertinoAction({ |
|
required this.title, |
|
required this.icon, |
|
required this.onPressed, |
|
Key? key, |
|
}) : super(key: key); |
|
|
|
final String title; |
|
final IconData icon; |
|
final VoidCallback onPressed; |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
final theme = Theme.of(context); |
|
return CupertinoActionSheetAction( |
|
onPressed: onPressed, |
|
child: Padding( |
|
padding: const EdgeInsets.symmetric(horizontal: 8), |
|
child: Row( |
|
children: [ |
|
Expanded( |
|
child: Text( |
|
title, |
|
textAlign: TextAlign.start, |
|
style: TextStyle(color: theme.colorScheme.onSurface), |
|
), |
|
), |
|
Icon( |
|
icon, |
|
size: theme.iconTheme.size, |
|
color: theme.colorScheme.onSurface.withOpacity(0.75), |
|
) |
|
], |
|
), |
|
), |
|
); |
|
} |
|
} |
|
|
|
Future<LinkMenuAction> _showMaterialMenu( |
|
BuildContext context, String link) async { |
|
final result = await showModalBottomSheet<LinkMenuAction>( |
|
context: context, |
|
builder: (ctx) { |
|
return Column( |
|
mainAxisSize: MainAxisSize.min, |
|
children: [ |
|
_MaterialAction( |
|
title: 'Open'.i18n, |
|
icon: Icons.language_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.launch), |
|
), |
|
_MaterialAction( |
|
title: 'Copy'.i18n, |
|
icon: Icons.copy_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.copy), |
|
), |
|
_MaterialAction( |
|
title: 'Remove'.i18n, |
|
icon: Icons.link_off_sharp, |
|
onPressed: () => Navigator.of(context).pop(LinkMenuAction.remove), |
|
), |
|
], |
|
); |
|
}, |
|
); |
|
|
|
return result ?? LinkMenuAction.none; |
|
} |
|
|
|
class _MaterialAction extends StatelessWidget { |
|
const _MaterialAction({ |
|
required this.title, |
|
required this.icon, |
|
required this.onPressed, |
|
Key? key, |
|
}) : super(key: key); |
|
|
|
final String title; |
|
final IconData icon; |
|
final VoidCallback onPressed; |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
final theme = Theme.of(context); |
|
return ListTile( |
|
leading: Icon( |
|
icon, |
|
size: theme.iconTheme.size, |
|
color: theme.colorScheme.onSurface.withOpacity(0.75), |
|
), |
|
title: Text(title), |
|
onTap: onPressed, |
|
); |
|
} |
|
}
|
|
|