mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: update UIs in document and move plugins out of package (#2289)
* chore: move plugins out of package * chore: update cover image picker style * chore: update math equation style * chore: rename barrel file * chore: add LocaleKeys
This commit is contained in:
parent
782d01274d
commit
40e266f5ce
@ -128,6 +128,7 @@
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Done": "Done",
|
||||
"Cancel": "Cancel",
|
||||
"signIn": "Sign In",
|
||||
"signOut": "Sign Out",
|
||||
@ -387,6 +388,10 @@
|
||||
"addIcon": "Add Icon",
|
||||
"coverRemoveAlert": "It will be removed from cover after it is deleted.",
|
||||
"alertDialogConfirmation": "Are you sure, you want to continue?"
|
||||
},
|
||||
"mathEquation": {
|
||||
"addMathEquation": "Add Math Equation",
|
||||
"editMathEquation": "Edit Math Equation"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,15 +1,6 @@
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/board/board_view_menu_item.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/plugins.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/board/board_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/grid/grid_menu_item.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/grid/grid_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/auto_completion_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/auto_completion_plugins.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/smart_edit_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/smart_edit_toolbar_item.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -20,8 +11,6 @@ import '../../startup/startup.dart';
|
||||
import 'application/doc_bloc.dart';
|
||||
import 'editor_styles.dart';
|
||||
import 'presentation/banner.dart';
|
||||
import 'presentation/plugins/grid/grid_view_menu_item.dart';
|
||||
import 'presentation/plugins/board/board_menu_item.dart';
|
||||
|
||||
class DocumentPage extends StatefulWidget {
|
||||
final VoidCallback onDeleted;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/src/emoji_picker/emoji_menu_item.dart';
|
||||
import 'package:appflowy_editor_plugins/src/extensions/theme_extension.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
@ -192,10 +191,12 @@ class _CalloutWidgetState extends State<_CalloutWidget> with SelectableMixin {
|
||||
Widget _buildColorPicker() {
|
||||
return FlowyColorPicker(
|
||||
colors: FlowyTint.values
|
||||
.map((t) => ColorOption(
|
||||
color: t.color(context),
|
||||
name: t.tintName(AppFlowyEditorLocalizations.current),
|
||||
))
|
||||
.map(
|
||||
(t) => ColorOption(
|
||||
color: t.color(context),
|
||||
name: t.tintName(AppFlowyEditorLocalizations.current),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
selected: tint.color(context),
|
||||
onTap: (color, index) {
|
@ -157,11 +157,11 @@ class __CodeBlockNodeWidgeState extends State<_CodeBlockNodeWidge>
|
||||
? TextSpan(text: node.value)
|
||||
: TextSpan(
|
||||
text: node.value,
|
||||
style: _builtInCodeBlockTheme[node.className!]));
|
||||
style: _builtInCodeBlockTheme[node.className!],),);
|
||||
} else if (node.children != null) {
|
||||
List<TextSpan> tmp = [];
|
||||
currentSpans.add(TextSpan(
|
||||
children: tmp, style: _builtInCodeBlockTheme[node.className!]));
|
||||
children: tmp, style: _builtInCodeBlockTheme[node.className!],),);
|
||||
stack.add(currentSpans);
|
||||
currentSpans = tmp;
|
||||
|
||||
@ -213,7 +213,7 @@ const _builtInCodeBlockTheme = {
|
||||
'attr': TextStyle(color: Color(0xff836C28)),
|
||||
'subst': TextStyle(color: Color(0xff000000)),
|
||||
'formula': TextStyle(
|
||||
backgroundColor: Color(0xffeeeeee), fontStyle: FontStyle.italic),
|
||||
backgroundColor: Color(0xffeeeeee), fontStyle: FontStyle.italic,),
|
||||
'addition': TextStyle(backgroundColor: Color(0xffbaeeba)),
|
||||
'deletion': TextStyle(backgroundColor: Color(0xffffc8bd)),
|
||||
'selector-id': TextStyle(color: Color(0xff9b703f)),
|
@ -1,5 +1,5 @@
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/src/code_block/code_block_node_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -2,11 +2,8 @@ import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/change_cover_popover_bloc.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_image_picker.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
@ -257,8 +254,6 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Theme.of(context).colorScheme.primary.withOpacity(0.15),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
@ -270,6 +265,8 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||
Icons.add,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
hoverColor:
|
||||
Theme.of(context).colorScheme.primary.withOpacity(0.15),
|
||||
width: 20,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
|
@ -145,7 +145,7 @@ class _NetworkImageUrlInputState extends State<NetworkImageUrlInput> {
|
||||
},
|
||||
hoverColor: Colors.transparent,
|
||||
fillColor: buttonDisabled
|
||||
? Colors.grey
|
||||
? Theme.of(context).disabledColor
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
height: 36,
|
||||
title: LocaleKeys.document_plugins_cover_add.tr(),
|
||||
@ -174,7 +174,7 @@ class ImagePickerActionButtons extends StatelessWidget {
|
||||
children: [
|
||||
FlowyTextButton(
|
||||
LocaleKeys.document_plugins_cover_back.tr(),
|
||||
hoverColor: Colors.transparent,
|
||||
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||
fillColor: Colors.transparent,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
onPressed: () => onBackPressed(),
|
||||
@ -182,7 +182,7 @@ class ImagePickerActionButtons extends StatelessWidget {
|
||||
FlowyTextButton(
|
||||
LocaleKeys.document_plugins_cover_saveToGallery.tr(),
|
||||
onPressed: () => onSave(),
|
||||
hoverColor: Colors.transparent,
|
||||
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||
fillColor: Colors.transparent,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
fontColor: Theme.of(context).colorScheme.primary,
|
||||
@ -204,48 +204,61 @@ class CoverImagePreviewWidget extends StatefulWidget {
|
||||
|
||||
class _CoverImagePreviewWidgetState extends State<CoverImagePreviewWidget> {
|
||||
_buildFilePickerWidget(BuildContext ctx) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
svgWidget(
|
||||
"editor/add",
|
||||
size: const Size(20, 20),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 3,
|
||||
),
|
||||
FlowyText(
|
||||
LocaleKeys.document_plugins_cover_pasteImageUrl.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FlowyText(
|
||||
LocaleKeys.document_plugins_cover_or.tr(),
|
||||
color: Colors.grey,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FlowyButton(
|
||||
onTap: () {
|
||||
ctx.read<CoverImagePickerBloc>().add(const PickFileImage());
|
||||
},
|
||||
useIntrinsicWidth: true,
|
||||
leftIcon: svgWidget(
|
||||
"file_icon",
|
||||
size: const Size(25, 25),
|
||||
),
|
||||
text: FlowyText(
|
||||
LocaleKeys.document_plugins_cover_pickFromFiles.tr(),
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: Corners.s6Border,
|
||||
border: Border.fromBorderSide(
|
||||
BorderSide(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const FlowySvg(
|
||||
name: 'editor/add',
|
||||
size: Size(20, 20),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 3,
|
||||
),
|
||||
FlowyText(
|
||||
LocaleKeys.document_plugins_cover_pasteImageUrl.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FlowyText(
|
||||
LocaleKeys.document_plugins_cover_or.tr(),
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FlowyButton(
|
||||
hoverColor: Theme.of(context).hoverColor,
|
||||
onTap: () {
|
||||
ctx.read<CoverImagePickerBloc>().add(const PickFileImage());
|
||||
},
|
||||
useIntrinsicWidth: true,
|
||||
leftIcon: const FlowySvg(
|
||||
name: 'file_icon',
|
||||
size: Size(20, 20),
|
||||
),
|
||||
text: FlowyText(
|
||||
LocaleKeys.document_plugins_cover_pickFromFiles.tr(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:appflowy/plugins/document/presentation/plugins/divider/divider_node_widget.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/src/divider/divider_node_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// insert divider into a document by typing three minuses.
|
@ -48,7 +48,7 @@ void _showEmojiSelectionMenu(
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},);
|
||||
|
||||
Overlay.of(context).insert(_emojiSelectionMenu!);
|
||||
|
@ -27,7 +27,7 @@ class Config {
|
||||
const TextStyle(fontSize: 20, color: Colors.black26),
|
||||
this.tabIndicatorAnimDuration = kTabScrollDuration,
|
||||
this.categoryIcons = const CategoryIcons(),
|
||||
this.buttonMode = ButtonMode.MATERIAL});
|
||||
this.buttonMode = ButtonMode.MATERIAL,});
|
||||
|
||||
/// Number of emojis per row
|
||||
final int columns;
|
@ -27,14 +27,14 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
@override
|
||||
void initState() {
|
||||
var initCategory = widget.state.categoryEmoji.indexWhere(
|
||||
(element) => element.category == widget.config.initCategory);
|
||||
(element) => element.category == widget.config.initCategory,);
|
||||
if (initCategory == -1) {
|
||||
initCategory = 0;
|
||||
}
|
||||
_tabController = TabController(
|
||||
initialIndex: initCategory,
|
||||
length: widget.state.categoryEmoji.length,
|
||||
vsync: this);
|
||||
vsync: this,);
|
||||
_pageController = PageController(initialPage: initCategory);
|
||||
_emojiFocusNode.requestFocus();
|
||||
|
||||
@ -79,7 +79,7 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
),
|
||||
onPressed: () {
|
||||
widget.state.onBackspacePressed!();
|
||||
}),
|
||||
},),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
@ -161,7 +161,7 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
.asMap()
|
||||
.entries
|
||||
.map<Widget>((item) => _buildCategory(
|
||||
item.value.category, emojiSize))
|
||||
item.value.category, emojiSize,),)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
@ -207,7 +207,7 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
}
|
||||
|
||||
Widget _buildButtonWidget(
|
||||
{required VoidCallback onPressed, required Widget child}) {
|
||||
{required VoidCallback onPressed, required Widget child,}) {
|
||||
if (widget.config.buttonMode == ButtonMode.MATERIAL) {
|
||||
return InkWell(
|
||||
onTap: onPressed,
|
||||
@ -279,7 +279,7 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
),
|
||||
));
|
||||
),);
|
||||
}
|
||||
|
||||
Widget _buildNoRecent() {
|
||||
@ -288,6 +288,6 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
widget.config.noRecentsText,
|
||||
style: widget.config.noRecentsStyle,
|
||||
textAlign: TextAlign.center,
|
||||
));
|
||||
),);
|
||||
}
|
||||
}
|
@ -191,29 +191,29 @@ class EmojiPickerState extends State<EmojiPicker> {
|
||||
}
|
||||
categoryEmoji.addAll([
|
||||
CategoryEmoji(Category.SMILEYS,
|
||||
await _getAvailableEmojis(emoji_list.smileys, title: 'smileys')),
|
||||
await _getAvailableEmojis(emoji_list.smileys, title: 'smileys'),),
|
||||
CategoryEmoji(Category.ANIMALS,
|
||||
await _getAvailableEmojis(emoji_list.animals, title: 'animals')),
|
||||
await _getAvailableEmojis(emoji_list.animals, title: 'animals'),),
|
||||
CategoryEmoji(Category.FOODS,
|
||||
await _getAvailableEmojis(emoji_list.foods, title: 'foods')),
|
||||
await _getAvailableEmojis(emoji_list.foods, title: 'foods'),),
|
||||
CategoryEmoji(
|
||||
Category.ACTIVITIES,
|
||||
await _getAvailableEmojis(emoji_list.activities,
|
||||
title: 'activities')),
|
||||
title: 'activities',),),
|
||||
CategoryEmoji(Category.TRAVEL,
|
||||
await _getAvailableEmojis(emoji_list.travel, title: 'travel')),
|
||||
await _getAvailableEmojis(emoji_list.travel, title: 'travel'),),
|
||||
CategoryEmoji(Category.OBJECTS,
|
||||
await _getAvailableEmojis(emoji_list.objects, title: 'objects')),
|
||||
await _getAvailableEmojis(emoji_list.objects, title: 'objects'),),
|
||||
CategoryEmoji(Category.SYMBOLS,
|
||||
await _getAvailableEmojis(emoji_list.symbols, title: 'symbols')),
|
||||
await _getAvailableEmojis(emoji_list.symbols, title: 'symbols'),),
|
||||
CategoryEmoji(Category.FLAGS,
|
||||
await _getAvailableEmojis(emoji_list.flags, title: 'flags'))
|
||||
await _getAvailableEmojis(emoji_list.flags, title: 'flags'),)
|
||||
]);
|
||||
}
|
||||
|
||||
// Get available emoji for given category title
|
||||
Future<List<Emoji>> _getAvailableEmojis(Map<String, String> map,
|
||||
{required String title}) async {
|
||||
{required String title,}) async {
|
||||
Map<String, String>? newMap;
|
||||
|
||||
// Get Emojis cached locally if available
|
||||
@ -236,7 +236,7 @@ class EmojiPickerState extends State<EmojiPicker> {
|
||||
|
||||
// Check if emoji is available on current platform
|
||||
Future<Map<String, String>?> _getPlatformAvailableEmoji(
|
||||
Map<String, String> emoji) async {
|
||||
Map<String, String> emoji,) async {
|
||||
if (Platform.isAndroid) {
|
||||
Map<String, String>? filtered = {};
|
||||
var delimiter = '|';
|
||||
@ -244,7 +244,7 @@ class EmojiPickerState extends State<EmojiPicker> {
|
||||
var entries = emoji.values.join(delimiter);
|
||||
var keys = emoji.keys.join(delimiter);
|
||||
var result = (await platform.invokeMethod<String>('checkAvailability',
|
||||
{'emojiKeys': keys, 'emojiEntries': entries})) as String;
|
||||
{'emojiKeys': keys, 'emojiEntries': entries},)) as String;
|
||||
var resultKeys = result.split(delimiter);
|
||||
for (var i = 0; i < resultKeys.length; i++) {
|
||||
filtered[resultKeys[i]] = emoji[resultKeys[i]]!;
|
||||
@ -272,7 +272,7 @@ class EmojiPickerState extends State<EmojiPicker> {
|
||||
|
||||
// Stores filtered emoji locally for faster access next time
|
||||
Future<void> _cacheFilteredEmojis(
|
||||
String title, Map<String, String> emojis) async {
|
||||
String title, Map<String, String> emojis,) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
var emojiJson = jsonEncode(emojis);
|
||||
prefs.setString(title, emojiJson);
|
||||
@ -305,7 +305,7 @@ class EmojiPickerState extends State<EmojiPicker> {
|
||||
recentEmoji.sort((a, b) => b.counter - a.counter);
|
||||
// Limit entries to recentsLimit
|
||||
recentEmoji = recentEmoji.sublist(
|
||||
0, min(widget.config.recentsLimit, recentEmoji.length));
|
||||
0, min(widget.config.recentsLimit, recentEmoji.length),);
|
||||
// save locally
|
||||
prefs.setString('recent', jsonEncode(recentEmoji));
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
@ -1,168 +0,0 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
ShortcutEvent insertHorizontalRule = ShortcutEvent(
|
||||
key: 'Horizontal rule',
|
||||
command: 'Minus',
|
||||
handler: _insertHorzaontalRule,
|
||||
);
|
||||
|
||||
ShortcutEventHandler _insertHorzaontalRule = (editorState, event) {
|
||||
final selection = editorState.service.selectionService.currentSelection.value;
|
||||
final textNodes = editorState.service.selectionService.currentSelectedNodes
|
||||
.whereType<TextNode>();
|
||||
if (textNodes.length != 1 || selection == null) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
final textNode = textNodes.first;
|
||||
if (textNode.toPlainText() == '--') {
|
||||
final transaction = editorState.transaction
|
||||
..deleteText(textNode, 0, 2)
|
||||
..insertNode(
|
||||
textNode.path,
|
||||
Node(
|
||||
type: 'horizontal_rule',
|
||||
children: LinkedList(),
|
||||
attributes: {},
|
||||
),
|
||||
)
|
||||
..afterSelection =
|
||||
Selection.single(path: textNode.path.next, startOffset: 0);
|
||||
editorState.apply(transaction);
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
return KeyEventResult.ignored;
|
||||
};
|
||||
|
||||
SelectionMenuItem horizontalRuleMenuItem = SelectionMenuItem(
|
||||
name: 'Horizontal rule',
|
||||
icon: (editorState, onSelected) => Icon(
|
||||
Icons.horizontal_rule,
|
||||
color: onSelected
|
||||
? editorState.editorStyle.selectionMenuItemSelectedIconColor
|
||||
: editorState.editorStyle.selectionMenuItemIconColor,
|
||||
size: 18.0,
|
||||
),
|
||||
keywords: ['horizontal rule'],
|
||||
handler: (editorState, _, __) {
|
||||
final selection =
|
||||
editorState.service.selectionService.currentSelection.value;
|
||||
final textNodes = editorState.service.selectionService.currentSelectedNodes
|
||||
.whereType<TextNode>();
|
||||
if (selection == null || textNodes.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final textNode = textNodes.first;
|
||||
if (textNode.toPlainText().isEmpty) {
|
||||
final transaction = editorState.transaction
|
||||
..insertNode(
|
||||
textNode.path,
|
||||
Node(
|
||||
type: 'horizontal_rule',
|
||||
children: LinkedList(),
|
||||
attributes: {},
|
||||
),
|
||||
)
|
||||
..afterSelection =
|
||||
Selection.single(path: textNode.path.next, startOffset: 0);
|
||||
editorState.apply(transaction);
|
||||
} else {
|
||||
final transaction = editorState.transaction
|
||||
..insertNode(
|
||||
selection.end.path.next,
|
||||
TextNode(
|
||||
children: LinkedList(),
|
||||
attributes: {
|
||||
'subtype': 'horizontal_rule',
|
||||
},
|
||||
delta: Delta()..insert('---'),
|
||||
),
|
||||
)
|
||||
..afterSelection = selection;
|
||||
editorState.apply(transaction);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
class HorizontalRuleWidgetBuilder extends NodeWidgetBuilder<Node> {
|
||||
@override
|
||||
Widget build(NodeWidgetContext<Node> context) {
|
||||
return _HorizontalRuleWidget(
|
||||
key: context.node.key,
|
||||
node: context.node,
|
||||
editorState: context.editorState,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
NodeValidator<Node> get nodeValidator => (node) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
class _HorizontalRuleWidget extends StatefulWidget {
|
||||
const _HorizontalRuleWidget({
|
||||
Key? key,
|
||||
required this.node,
|
||||
required this.editorState,
|
||||
}) : super(key: key);
|
||||
|
||||
final Node node;
|
||||
final EditorState editorState;
|
||||
|
||||
@override
|
||||
State<_HorizontalRuleWidget> createState() => __HorizontalRuleWidgetState();
|
||||
}
|
||||
|
||||
class __HorizontalRuleWidgetState extends State<_HorizontalRuleWidget>
|
||||
with SelectableMixin {
|
||||
RenderBox get _renderBox => context.findRenderObject() as RenderBox;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Position start() => Position(path: widget.node.path, offset: 0);
|
||||
|
||||
@override
|
||||
Position end() => Position(path: widget.node.path, offset: 1);
|
||||
|
||||
@override
|
||||
Position getPositionInOffset(Offset start) => end();
|
||||
|
||||
@override
|
||||
bool get shouldCursorBlink => false;
|
||||
|
||||
@override
|
||||
CursorStyle get cursorStyle => CursorStyle.borderLine;
|
||||
|
||||
@override
|
||||
Rect? getCursorRectInPosition(Position position) {
|
||||
final size = _renderBox.size;
|
||||
return Rect.fromLTWH(-size.width / 2.0, 0, size.width, size.height);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Rect> getRectsInSelection(Selection selection) =>
|
||||
[Offset.zero & _renderBox.size];
|
||||
|
||||
@override
|
||||
Selection getSelectionInRange(Offset start, Offset end) => Selection.single(
|
||||
path: widget.node.path,
|
||||
startOffset: 0,
|
||||
endOffset: 1,
|
||||
);
|
||||
|
||||
@override
|
||||
Offset localToGlobal(Offset offset) => _renderBox.localToGlobal(offset);
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/secondary_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_math_fork/flutter_math.dart';
|
||||
@ -131,14 +136,14 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
|
||||
color: _isHover || _mathEquation.isEmpty
|
||||
? Colors.grey[200]
|
||||
? Theme.of(context).colorScheme.tertiaryContainer
|
||||
: Colors.transparent,
|
||||
),
|
||||
child: Center(
|
||||
child: _mathEquation.isEmpty
|
||||
? Text(
|
||||
'Add a Math Equation',
|
||||
style: widget.editorState.editorStyle.placeholderTextStyle,
|
||||
? FlowyText.medium(
|
||||
LocaleKeys.document_plugins_mathEquation_addMathEquation.tr(),
|
||||
fontSize: 16,
|
||||
)
|
||||
: Math.tex(
|
||||
_mathEquation,
|
||||
@ -155,7 +160,10 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
|
||||
builder: (context) {
|
||||
final controller = TextEditingController(text: _mathEquation);
|
||||
return AlertDialog(
|
||||
title: const Text('Edit Math Equation'),
|
||||
backgroundColor: Theme.of(context).canvasColor,
|
||||
title: Text(
|
||||
LocaleKeys.document_plugins_mathEquation_editMathEquation.tr(),
|
||||
),
|
||||
content: RawKeyboardListener(
|
||||
focusNode: FocusNode(),
|
||||
onKey: (key) {
|
||||
@ -178,15 +186,17 @@ class _MathEquationNodeWidgetState extends State<_MathEquationNodeWidget> {
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
SecondaryTextButton(
|
||||
LocaleKeys.button_Cancel.tr(),
|
||||
onPressed: () => _dismiss(context),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
PrimaryTextButton(
|
||||
LocaleKeys.button_Done.tr(),
|
||||
onPressed: () => _updateMathEquation(controller.text, context),
|
||||
child: const Text('Done'),
|
||||
),
|
||||
],
|
||||
actionsPadding: const EdgeInsets.only(bottom: 20),
|
||||
actionsAlignment: MainAxisAlignment.spaceAround,
|
||||
);
|
||||
},
|
||||
);
|
@ -0,0 +1,21 @@
|
||||
export 'board/board_node_widget.dart';
|
||||
export 'board/board_menu_item.dart';
|
||||
export 'board/board_view_menu_item.dart';
|
||||
export 'callout/callout_node_widget.dart';
|
||||
export 'code_block/code_block_node_widget.dart';
|
||||
export 'code_block/code_block_shortcut_event.dart';
|
||||
export 'cover/change_cover_popover_bloc.dart';
|
||||
export 'cover/cover_node_widget.dart';
|
||||
export 'cover/cover_image_picker.dart';
|
||||
export 'divider/divider_node_widget.dart';
|
||||
export 'divider/divider_shortcut_event.dart';
|
||||
export 'emoji_picker/emoji_menu_item.dart';
|
||||
export 'extensions/flowy_tint_extension.dart';
|
||||
export 'grid/grid_menu_item.dart';
|
||||
export 'grid/grid_node_widget.dart';
|
||||
export 'grid/grid_view_menu_item.dart';
|
||||
export 'math_equation/math_equation_node_widget.dart';
|
||||
export 'openai/widgets/auto_completion_node_widget.dart';
|
||||
export 'openai/widgets/auto_completion_plugins.dart';
|
||||
export 'openai/widgets/smart_edit_node_widget.dart';
|
||||
export 'openai/widgets/smart_edit_toolbar_item.dart';
|
@ -1,30 +0,0 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
/pubspec.lock
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.packages
|
||||
build/
|
@ -1,10 +0,0 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
channel: unknown
|
||||
|
||||
project_type: package
|
@ -1,3 +0,0 @@
|
||||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
@ -1 +0,0 @@
|
||||
TODO: Add your license here.
|
@ -1,39 +0,0 @@
|
||||
<!--
|
||||
This README describes the package. If you publish this package to pub.dev,
|
||||
this README's contents appear on the landing page for your package.
|
||||
|
||||
For information about how to write a good package README, see the guide for
|
||||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||
-->
|
||||
|
||||
TODO: Put a short description of the package here that helps potential users
|
||||
know whether this package might be useful for them.
|
||||
|
||||
## Features
|
||||
|
||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||
|
||||
## Getting started
|
||||
|
||||
TODO: List prerequisites and provide or point to information on how to
|
||||
start using the package.
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Include short and useful examples for package users. Add longer examples
|
||||
to `/example` folder.
|
||||
|
||||
```dart
|
||||
const like = 'sample';
|
||||
```
|
||||
|
||||
## Additional information
|
||||
|
||||
TODO: Tell users more about the package: where to find more information, how to
|
||||
contribute to the package, how to file issues, what response they can expect
|
||||
from the package authors, and more.
|
@ -1,4 +0,0 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
@ -1,6 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 4.3999H4.11111H13" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.77799 4.4V3.2C5.77799 2.88174 5.89506 2.57652 6.10343 2.35147C6.31181 2.12643 6.59442 2 6.88911 2H9.11133C9.40601 2 9.68863 2.12643 9.897 2.35147C10.1054 2.57652 10.2224 2.88174 10.2224 3.2V4.4M11.8891 4.4V12.8C11.8891 13.1183 11.772 13.4235 11.5637 13.6485C11.3553 13.8736 11.0727 14 10.778 14H5.22244C4.92775 14 4.64514 13.8736 4.43676 13.6485C4.22839 13.4235 4.11133 13.1183 4.11133 12.8V4.4H11.8891Z" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.88867 7.3999V10.9999" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.11133 7.3999V10.9999" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 875 B |
@ -1,16 +0,0 @@
|
||||
library appflowy_editor_plugins;
|
||||
|
||||
// Callout
|
||||
export 'src/callout/callout_node_widget.dart';
|
||||
// Code Block
|
||||
export 'src/code_block/code_block_node_widget.dart';
|
||||
export 'src/code_block/code_block_shortcut_event.dart';
|
||||
// Divider
|
||||
export 'src/divider/divider_node_widget.dart';
|
||||
export 'src/divider/divider_shortcut_event.dart';
|
||||
// Emoji Picker
|
||||
export 'src/emoji_picker/emoji_menu_item.dart';
|
||||
// Math Equation
|
||||
export 'src/math_equation/math_equation_node_widget.dart';
|
||||
|
||||
export 'src/extensions/theme_extension.dart';
|
@ -1,71 +0,0 @@
|
||||
name: appflowy_editor_plugins
|
||||
description: A new Flutter package project.
|
||||
version: 0.0.1
|
||||
homepage: https://github.com/AppFlowy-IO/AppFlowy
|
||||
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
flutter: ">=3.7.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
appflowy_editor: ^0.1.5
|
||||
flowy_infra:
|
||||
path: ../flowy_infra
|
||||
flowy_infra_ui:
|
||||
path: ../flowy_infra_ui
|
||||
appflowy_popover:
|
||||
path: ../appflowy_popover
|
||||
flutter_math_fork:
|
||||
git:
|
||||
url: https://github.com/LucasXu0/flutter_math_fork.git
|
||||
ref: master
|
||||
highlight: ^0.7.0
|
||||
shared_preferences: ^2.0.15
|
||||
flutter_svg: ^2.0.2
|
||||
provider: ^6.0.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
|
||||
# To add assets to your package, add an assets section, like this:
|
||||
assets:
|
||||
- assets/images/
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
# To add custom fonts to your package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/custom-fonts/#from-packages
|
@ -1 +0,0 @@
|
||||
|
@ -154,7 +154,7 @@ class FlowyTextButton extends StatelessWidget {
|
||||
overflow: overflow,
|
||||
fontWeight: fontWeight,
|
||||
fontSize: fontSize,
|
||||
color: fontColor ?? Theme.of(context).colorScheme.onSecondary,
|
||||
color: fontColor,
|
||||
textAlign: TextAlign.center,
|
||||
decoration: decoration,
|
||||
),
|
||||
|
@ -49,13 +49,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
appflowy_editor_plugins:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "packages/appflowy_editor_plugins"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
appflowy_popover:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -515,7 +508,7 @@ packages:
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_math_fork:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
@ -532,13 +525,13 @@ packages:
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
flutter_svg:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: "12006889e2987c549c4c1ec1a5ba4ec4b24d34d2469ee5f9476c926dcecff266"
|
||||
sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -619,7 +612,7 @@ packages:
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
highlight:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: highlight
|
||||
sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
|
||||
|
@ -53,6 +53,10 @@ dependencies:
|
||||
freezed_annotation: ^2.1.0
|
||||
get_it: "^7.1.3"
|
||||
flutter_bloc: "^8.0.1"
|
||||
flutter_math_fork:
|
||||
git:
|
||||
url: https://github.com/LucasXu0/flutter_math_fork.git
|
||||
ref: master
|
||||
dartz: ^0.10.1
|
||||
provider: ^6.0.1
|
||||
path_provider: ^2.0.1
|
||||
@ -60,6 +64,7 @@ dependencies:
|
||||
styled_widget: "^0.3.1"
|
||||
expandable: ^5.0.1
|
||||
flutter_colorpicker: ^1.0.3
|
||||
highlight: ^0.7.0
|
||||
package_info_plus: ^1.3.0
|
||||
url_launcher: ^6.0.2
|
||||
# file_picker: ^4.2.1
|
||||
@ -88,14 +93,13 @@ dependencies:
|
||||
google_fonts: ^4.0.3
|
||||
file_picker: <=5.0.0
|
||||
percent_indicator: ^4.0.1
|
||||
appflowy_editor_plugins:
|
||||
path: packages/appflowy_editor_plugins
|
||||
calendar_view: ^1.0.1
|
||||
window_manager: ^0.3.0
|
||||
http: ^0.13.5
|
||||
json_annotation: ^4.7.0
|
||||
path: ^1.8.2
|
||||
archive: ^3.3.0
|
||||
flutter_svg: ^2.0.5
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user