mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: improve editing link user experience (#3990)
This commit is contained in:
parent
0427402ba7
commit
8afbf28430
@ -5,13 +5,13 @@ import 'package:flutter/material.dart';
|
|||||||
class BottomSheetActionWidget extends StatelessWidget {
|
class BottomSheetActionWidget extends StatelessWidget {
|
||||||
const BottomSheetActionWidget({
|
const BottomSheetActionWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.svg,
|
this.svg,
|
||||||
required this.text,
|
required this.text,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.iconColor,
|
this.iconColor,
|
||||||
});
|
});
|
||||||
|
|
||||||
final FlowySvgData svg;
|
final FlowySvgData? svg;
|
||||||
final String text;
|
final String text;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final Color? iconColor;
|
final Color? iconColor;
|
||||||
@ -21,9 +21,23 @@ class BottomSheetActionWidget extends StatelessWidget {
|
|||||||
final iconColor =
|
final iconColor =
|
||||||
this.iconColor ?? Theme.of(context).colorScheme.onBackground;
|
this.iconColor ?? Theme.of(context).colorScheme.onBackground;
|
||||||
|
|
||||||
|
if (svg == null) {
|
||||||
|
return OutlinedButton(
|
||||||
|
style: Theme.of(context)
|
||||||
|
.outlinedButtonTheme
|
||||||
|
.style
|
||||||
|
?.copyWith(alignment: Alignment.center),
|
||||||
|
onPressed: onTap,
|
||||||
|
child: FlowyText(
|
||||||
|
text,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return OutlinedButton.icon(
|
return OutlinedButton.icon(
|
||||||
icon: FlowySvg(
|
icon: FlowySvg(
|
||||||
svg,
|
svg!,
|
||||||
size: const Size.square(22.0),
|
size: const Size.square(22.0),
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
),
|
),
|
||||||
|
@ -0,0 +1,127 @@
|
|||||||
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:string_validator/string_validator.dart';
|
||||||
|
|
||||||
|
class MobileBottomSheetEditLinkWidget extends StatefulWidget {
|
||||||
|
const MobileBottomSheetEditLinkWidget({
|
||||||
|
super.key,
|
||||||
|
required this.text,
|
||||||
|
required this.href,
|
||||||
|
required this.onEdit,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String text;
|
||||||
|
final String? href;
|
||||||
|
final void Function(String text, String href) onEdit;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MobileBottomSheetEditLinkWidget> createState() =>
|
||||||
|
_MobileBottomSheetEditLinkWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MobileBottomSheetEditLinkWidgetState
|
||||||
|
extends State<MobileBottomSheetEditLinkWidget> {
|
||||||
|
late final TextEditingController textController;
|
||||||
|
late final TextEditingController hrefController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
textController = TextEditingController(
|
||||||
|
text: widget.text,
|
||||||
|
);
|
||||||
|
hrefController = TextEditingController(
|
||||||
|
text: widget.href,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
textController.dispose();
|
||||||
|
hrefController.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 4.0,
|
||||||
|
vertical: 16.0,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_buildTextField(textController, null),
|
||||||
|
const VSpace(12.0),
|
||||||
|
_buildTextField(hrefController, LocaleKeys.editor_linkTextHint.tr()),
|
||||||
|
const VSpace(12.0),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: BottomSheetActionWidget(
|
||||||
|
text: LocaleKeys.button_cancel.tr(),
|
||||||
|
onTap: () => context.pop(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const HSpace(8),
|
||||||
|
Expanded(
|
||||||
|
child: BottomSheetActionWidget(
|
||||||
|
text: LocaleKeys.button_done.tr(),
|
||||||
|
onTap: () {
|
||||||
|
widget.onEdit(textController.text, hrefController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.href != null && isURL(widget.href)) ...[
|
||||||
|
const HSpace(8),
|
||||||
|
Expanded(
|
||||||
|
child: BottomSheetActionWidget(
|
||||||
|
text: LocaleKeys.editor_openLink.tr(),
|
||||||
|
onTap: () {
|
||||||
|
safeLaunchUrl(widget.href!);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTextField(
|
||||||
|
TextEditingController controller,
|
||||||
|
String? hintText,
|
||||||
|
) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 44.0,
|
||||||
|
child: FlowyTextField(
|
||||||
|
controller: controller,
|
||||||
|
hintText: hintText,
|
||||||
|
suffixIcon: Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: FlowyButton(
|
||||||
|
text: const FlowySvg(
|
||||||
|
FlowySvgs.close_lg,
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
useIntrinsicWidth: true,
|
||||||
|
onTap: () {
|
||||||
|
controller.clear();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,6 @@ List<MobileToolbarItem> getMobileToolbarItems() {
|
|||||||
buildTextAndBackgroundColorMobileToolbarItem(),
|
buildTextAndBackgroundColorMobileToolbarItem(),
|
||||||
mobileAddBlockToolbarItem,
|
mobileAddBlockToolbarItem,
|
||||||
mobileConvertBlockToolbarItem,
|
mobileConvertBlockToolbarItem,
|
||||||
linkMobileToolbarItem,
|
|
||||||
imageMobileToolbarItem,
|
imageMobileToolbarItem,
|
||||||
mobileAlignToolbarItem,
|
mobileAlignToolbarItem,
|
||||||
mobileIndentToolbarItem,
|
mobileIndentToolbarItem,
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/utils.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
final customTextDecorationMobileToolbarItem = MobileToolbarItem.withMenu(
|
final customTextDecorationMobileToolbarItem = MobileToolbarItem.withMenu(
|
||||||
itemIconBuilder: (_, __, ___) => const FlowySvg(
|
itemIconBuilder: (_, __, ___) => const FlowySvg(
|
||||||
FlowySvgs.text_s,
|
FlowySvgs.text_s,
|
||||||
size: Size.square(24),
|
size: Size.square(24),
|
||||||
),
|
),
|
||||||
itemMenuBuilder: (_, editorState, __) {
|
itemMenuBuilder: (_, editorState, service) {
|
||||||
final selection = editorState.selection;
|
final selection = editorState.selection;
|
||||||
if (selection == null) {
|
if (selection == null) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return _TextDecorationMenu(editorState, selection);
|
return _TextDecorationMenu(
|
||||||
|
editorState,
|
||||||
|
selection,
|
||||||
|
service,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -21,16 +27,20 @@ class _TextDecorationMenu extends StatefulWidget {
|
|||||||
const _TextDecorationMenu(
|
const _TextDecorationMenu(
|
||||||
this.editorState,
|
this.editorState,
|
||||||
this.selection,
|
this.selection,
|
||||||
|
this.service,
|
||||||
);
|
);
|
||||||
|
|
||||||
final EditorState editorState;
|
final EditorState editorState;
|
||||||
final Selection selection;
|
final Selection selection;
|
||||||
|
final MobileToolbarWidgetService service;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_TextDecorationMenu> createState() => _TextDecorationMenuState();
|
State<_TextDecorationMenu> createState() => _TextDecorationMenuState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
||||||
|
EditorState get editorState => widget.editorState;
|
||||||
|
|
||||||
final textDecorations = [
|
final textDecorations = [
|
||||||
// BIUS
|
// BIUS
|
||||||
TextDecorationUnit(
|
TextDecorationUnit(
|
||||||
@ -60,41 +70,90 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
|||||||
label: AppFlowyEditorL10n.current.embedCode,
|
label: AppFlowyEditorL10n.current.embedCode,
|
||||||
name: AppFlowyRichTextKeys.code,
|
name: AppFlowyRichTextKeys.code,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// link
|
||||||
|
TextDecorationUnit(
|
||||||
|
icon: AFMobileIcons.link,
|
||||||
|
label: AppFlowyEditorL10n.current.link,
|
||||||
|
name: AppFlowyRichTextKeys.href,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bius = textDecorations.map((currentDecoration) {
|
final children = textDecorations
|
||||||
// Check current decoration is active or not
|
.map((currentDecoration) {
|
||||||
final selection = widget.selection;
|
// Check current decoration is active or not
|
||||||
final nodes = widget.editorState.getNodesInSelection(selection);
|
final selection = widget.selection;
|
||||||
final bool isSelected;
|
|
||||||
if (selection.isCollapsed) {
|
|
||||||
isSelected = widget.editorState.toggledStyle.containsKey(
|
|
||||||
currentDecoration.name,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
isSelected = nodes.allSatisfyInSelection(selection, (delta) {
|
|
||||||
return delta.everyAttributes(
|
|
||||||
(attributes) => attributes[currentDecoration.name] == true,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return MobileToolbarItemMenuBtn(
|
// only show edit link bottom sheet when selection is not collapsed
|
||||||
icon: AFMobileIcon(
|
if (selection.isCollapsed &&
|
||||||
afMobileIcons: currentDecoration.icon,
|
currentDecoration.name == AppFlowyRichTextKeys.href) {
|
||||||
color: MobileToolbarTheme.of(context).iconColor,
|
return null;
|
||||||
),
|
}
|
||||||
label: FlowyText(currentDecoration.label),
|
|
||||||
isSelected: isSelected,
|
final nodes = editorState.getNodesInSelection(selection);
|
||||||
onPressed: () {
|
final bool isSelected;
|
||||||
setState(() {
|
if (selection.isCollapsed) {
|
||||||
widget.editorState.toggleAttribute(currentDecoration.name);
|
isSelected = editorState.toggledStyle.containsKey(
|
||||||
});
|
currentDecoration.name,
|
||||||
},
|
);
|
||||||
);
|
} else {
|
||||||
}).toList();
|
isSelected = nodes.allSatisfyInSelection(selection, (delta) {
|
||||||
|
return delta.everyAttributes(
|
||||||
|
(attributes) => attributes[currentDecoration.name] == true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return MobileToolbarItemMenuBtn(
|
||||||
|
icon: AFMobileIcon(
|
||||||
|
afMobileIcons: currentDecoration.icon,
|
||||||
|
color: MobileToolbarTheme.of(context).iconColor,
|
||||||
|
),
|
||||||
|
label: FlowyText(currentDecoration.label),
|
||||||
|
isSelected: isSelected,
|
||||||
|
onPressed: () {
|
||||||
|
if (currentDecoration.name == AppFlowyRichTextKeys.href) {
|
||||||
|
if (selection.isCollapsed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_closeKeyboard();
|
||||||
|
|
||||||
|
// show edit link bottom sheet
|
||||||
|
final context = nodes.firstOrNull?.context;
|
||||||
|
if (context != null) {
|
||||||
|
final text = editorState
|
||||||
|
.getTextInSelection(
|
||||||
|
widget.selection,
|
||||||
|
)
|
||||||
|
.join('');
|
||||||
|
final href =
|
||||||
|
editorState.getDeltaAttributeValueInSelection<String>(
|
||||||
|
AppFlowyRichTextKeys.href,
|
||||||
|
widget.selection,
|
||||||
|
);
|
||||||
|
showEditLinkBottomSheet(
|
||||||
|
context,
|
||||||
|
text,
|
||||||
|
href,
|
||||||
|
(context, newText, newHref) {
|
||||||
|
_updateTextAndHref(text, href, newText, newHref);
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
editorState.toggleAttribute(currentDecoration.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.nonNulls
|
||||||
|
.toList();
|
||||||
|
|
||||||
return GridView.count(
|
return GridView.count(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
@ -103,7 +162,49 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
|||||||
mainAxisSpacing: 8,
|
mainAxisSpacing: 8,
|
||||||
crossAxisSpacing: 8,
|
crossAxisSpacing: 8,
|
||||||
childAspectRatio: 4,
|
childAspectRatio: 4,
|
||||||
children: bius,
|
children: children,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _closeKeyboard() {
|
||||||
|
editorState.updateSelectionWithReason(
|
||||||
|
widget.selection,
|
||||||
|
extraInfo: {
|
||||||
|
disableMobileToolbarKey: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
editorState.service.keyboardService?.closeKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateTextAndHref(
|
||||||
|
String prevText,
|
||||||
|
String? prevHref,
|
||||||
|
String text,
|
||||||
|
String href,
|
||||||
|
) async {
|
||||||
|
final selection = widget.selection;
|
||||||
|
if (!selection.isSingle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final node = editorState.getNodeAtPath(selection.start.path);
|
||||||
|
if (node == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final transaction = editorState.transaction;
|
||||||
|
if (prevText != text) {
|
||||||
|
transaction.replaceText(
|
||||||
|
node,
|
||||||
|
selection.startIndex,
|
||||||
|
selection.length,
|
||||||
|
text,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// if the text is empty, it means the user wants to remove the text
|
||||||
|
if (text.isNotEmpty && prevHref != href) {
|
||||||
|
transaction.formatText(node, selection.startIndex, text.length, {
|
||||||
|
AppFlowyRichTextKeys.href: href.isEmpty ? null : href,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await editorState.apply(transaction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_edit_link_widget.dart';
|
||||||
|
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
void showEditLinkBottomSheet(
|
||||||
|
BuildContext context,
|
||||||
|
String text,
|
||||||
|
String? href,
|
||||||
|
void Function(BuildContext context, String text, String href) onEdit,
|
||||||
|
) {
|
||||||
|
assert(text.isNotEmpty);
|
||||||
|
showFlowyMobileBottomSheet(
|
||||||
|
context,
|
||||||
|
title: LocaleKeys.editor_editLink.tr(),
|
||||||
|
builder: (context) {
|
||||||
|
return MobileBottomSheetEditLinkWidget(
|
||||||
|
text: text,
|
||||||
|
href: href,
|
||||||
|
onEdit: (text, href) => onEdit(context, text, href),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -2,6 +2,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/inline_math_equation/inline_math_equation.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/inline_math_equation/inline_math_equation.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
||||||
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/utils.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart';
|
||||||
import 'package:appflowy/util/google_font_family_extension.dart';
|
import 'package:appflowy/util/google_font_family_extension.dart';
|
||||||
@ -10,6 +11,7 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
class EditorStyleCustomizer {
|
class EditorStyleCustomizer {
|
||||||
@ -276,7 +278,23 @@ class EditorStyleCustomizer {
|
|||||||
text: text.text,
|
text: text.text,
|
||||||
recognizer: TapGestureRecognizer()
|
recognizer: TapGestureRecognizer()
|
||||||
..onTap = () {
|
..onTap = () {
|
||||||
safeLaunchUrl(href);
|
showEditLinkBottomSheet(
|
||||||
|
context,
|
||||||
|
text.text,
|
||||||
|
href,
|
||||||
|
(linkContext, newText, newHref) {
|
||||||
|
_updateTextAndHref(
|
||||||
|
context,
|
||||||
|
node,
|
||||||
|
index,
|
||||||
|
text.text,
|
||||||
|
href,
|
||||||
|
newText,
|
||||||
|
newHref,
|
||||||
|
);
|
||||||
|
linkContext.pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -289,4 +307,37 @@ class EditorStyleCustomizer {
|
|||||||
textSpan,
|
textSpan,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _updateTextAndHref(
|
||||||
|
BuildContext context,
|
||||||
|
Node node,
|
||||||
|
int index,
|
||||||
|
String prevText,
|
||||||
|
String? prevHref,
|
||||||
|
String text,
|
||||||
|
String href,
|
||||||
|
) async {
|
||||||
|
final selection = Selection.single(
|
||||||
|
path: node.path,
|
||||||
|
startOffset: index,
|
||||||
|
endOffset: index + prevText.length,
|
||||||
|
);
|
||||||
|
final editorState = context.read<EditorState>();
|
||||||
|
final transaction = editorState.transaction;
|
||||||
|
if (prevText != text) {
|
||||||
|
transaction.replaceText(
|
||||||
|
node,
|
||||||
|
selection.startIndex,
|
||||||
|
selection.length,
|
||||||
|
text,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// if the text is empty, it means the user wants to remove the text
|
||||||
|
if (text.isNotEmpty && prevHref != href) {
|
||||||
|
transaction.formatText(node, selection.startIndex, text.length, {
|
||||||
|
AppFlowyRichTextKeys.href: href.isEmpty ? null : href,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await editorState.apply(transaction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int64_t init_sdk(char *path);
|
int64_t init_sdk(char *data);
|
||||||
|
|
||||||
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
||||||
|
|
||||||
|
@ -54,11 +54,11 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "4f073f3"
|
ref: "31acaff"
|
||||||
resolved-ref: "4f073f3381a05a2379144f282c6f65462c4ce9c6"
|
resolved-ref: "31acaff4f0bcd36a2946c9351dc1b5b5601b3994"
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "2.0.0-beta.1"
|
version: "2.0.0"
|
||||||
appflowy_popover:
|
appflowy_popover:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1114,6 +1114,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
numerus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: numerus
|
||||||
|
sha256: ada1b55e4a505b8e4578218e57be1ce4b7968bb0e51d824082ac0c74ef18a10d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
octo_image:
|
octo_image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -47,7 +47,7 @@ dependencies:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: 'ec3ecf5'
|
ref: '31acaff'
|
||||||
|
|
||||||
appflowy_popover:
|
appflowy_popover:
|
||||||
path: packages/appflowy_popover
|
path: packages/appflowy_popover
|
||||||
|
Loading…
Reference in New Issue
Block a user