| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | import 'package:appflowy/generated/flowy_svgs.g.dart'; | 
					
						
							|  |  |  | import 'package:appflowy/generated/locale_keys.g.dart'; | 
					
						
							|  |  |  | import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  | import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart'; | 
					
						
							| 
									
										
										
										
											2023-11-22 10:49:22 +08:00
										 |  |  | import 'package:appflowy_editor/appflowy_editor.dart'; | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | import 'package:easy_localization/easy_localization.dart'; | 
					
						
							|  |  |  | import 'package:flowy_infra_ui/flowy_infra_ui.dart'; | 
					
						
							|  |  |  | import 'package:flowy_infra_ui/style_widget/hover.dart'; | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | extension ToProto on FlowyIconType { | 
					
						
							|  |  |  |   ViewIconTypePB toProto() { | 
					
						
							|  |  |  |     switch (this) { | 
					
						
							|  |  |  |       case FlowyIconType.emoji: | 
					
						
							|  |  |  |         return ViewIconTypePB.Emoji; | 
					
						
							|  |  |  |       case FlowyIconType.icon: | 
					
						
							|  |  |  |         return ViewIconTypePB.Icon; | 
					
						
							|  |  |  |       case FlowyIconType.custom: | 
					
						
							|  |  |  |         return ViewIconTypePB.Url; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum FlowyIconType { | 
					
						
							|  |  |  |   emoji, | 
					
						
							|  |  |  |   icon, | 
					
						
							|  |  |  |   custom; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 21:10:29 +08:00
										 |  |  | class EmojiPickerResult { | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |   factory EmojiPickerResult.none() => | 
					
						
							|  |  |  |       const EmojiPickerResult(FlowyIconType.icon, ''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   factory EmojiPickerResult.emoji(String emoji) => | 
					
						
							|  |  |  |       EmojiPickerResult(FlowyIconType.emoji, emoji); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 21:10:29 +08:00
										 |  |  |   const EmojiPickerResult( | 
					
						
							|  |  |  |     this.type, | 
					
						
							|  |  |  |     this.emoji, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final FlowyIconType type; | 
					
						
							|  |  |  |   final String emoji; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  | class FlowyIconPicker extends StatelessWidget { | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |   const FlowyIconPicker({ | 
					
						
							|  |  |  |     super.key, | 
					
						
							|  |  |  |     required this.onSelected, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 21:10:29 +08:00
										 |  |  |   final void Function(EmojiPickerResult result) onSelected; | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     // ONLY supports emoji picker for now
 | 
					
						
							|  |  |  |     return DefaultTabController( | 
					
						
							|  |  |  |       length: 1, | 
					
						
							|  |  |  |       child: Column( | 
					
						
							|  |  |  |         mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |         children: [ | 
					
						
							|  |  |  |           Row( | 
					
						
							|  |  |  |             children: [ | 
					
						
							|  |  |  |               _buildTabs(context), | 
					
						
							|  |  |  |               const Spacer(), | 
					
						
							|  |  |  |               _RemoveIconButton( | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |                 onTap: () => onSelected(EmojiPickerResult.none()), | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |               ), | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |           ), | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |           const Divider(height: 2), | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |           Expanded( | 
					
						
							|  |  |  |             child: TabBarView( | 
					
						
							|  |  |  |               children: [ | 
					
						
							|  |  |  |                 FlowyEmojiPicker( | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |                   emojiPerLine: _getEmojiPerLine(context), | 
					
						
							|  |  |  |                   onEmojiSelected: (_, emoji) => | 
					
						
							|  |  |  |                       onSelected(EmojiPickerResult.emoji(emoji)), | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |                 ), | 
					
						
							|  |  |  |               ], | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Widget _buildTabs(BuildContext context) { | 
					
						
							|  |  |  |     return Align( | 
					
						
							|  |  |  |       alignment: Alignment.centerLeft, | 
					
						
							|  |  |  |       child: TabBar( | 
					
						
							|  |  |  |         indicatorSize: TabBarIndicatorSize.label, | 
					
						
							|  |  |  |         isScrollable: true, | 
					
						
							|  |  |  |         overlayColor: MaterialStatePropertyAll( | 
					
						
							|  |  |  |           Theme.of(context).colorScheme.secondary, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         padding: EdgeInsets.zero, | 
					
						
							|  |  |  |         tabs: [ | 
					
						
							|  |  |  |           FlowyHover( | 
					
						
							|  |  |  |             style: const HoverStyle(borderRadius: BorderRadius.zero), | 
					
						
							|  |  |  |             child: Padding( | 
					
						
							|  |  |  |               padding: const EdgeInsets.symmetric( | 
					
						
							|  |  |  |                 horizontal: 12.0, | 
					
						
							|  |  |  |                 vertical: 8.0, | 
					
						
							|  |  |  |               ), | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |               child: FlowyText(LocaleKeys.emoji_emojiTab.tr()), | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2023-11-14 22:33:07 +08:00
										 |  |  |           ), | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-11-17 13:51:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |   int _getEmojiPerLine(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2023-11-22 10:49:22 +08:00
										 |  |  |     if (PlatformExtension.isDesktopOrWeb) { | 
					
						
							|  |  |  |       return 9; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-17 13:51:26 +08:00
										 |  |  |     final width = MediaQuery.of(context).size.width; | 
					
						
							|  |  |  |     return width ~/ 46.0; // the size of the emoji
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _RemoveIconButton extends StatelessWidget { | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  |   const _RemoveIconButton({required this.onTap}); | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   final VoidCallback onTap; | 
					
						
							| 
									
										
										
										
											2024-04-12 10:21:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return SizedBox( | 
					
						
							|  |  |  |       height: 28, | 
					
						
							|  |  |  |       child: FlowyButton( | 
					
						
							|  |  |  |         onTap: onTap, | 
					
						
							|  |  |  |         useIntrinsicWidth: true, | 
					
						
							| 
									
										
										
										
											2023-12-05 10:46:17 +08:00
										 |  |  |         text: FlowyText.small( | 
					
						
							| 
									
										
										
										
											2023-11-02 15:24:17 +08:00
										 |  |  |           LocaleKeys.document_plugins_cover_removeIcon.tr(), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         leftIcon: const FlowySvg(FlowySvgs.delete_s), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |