fix: outline doesn't show when @dates are used in the headline (#8049)

* fix: outline doesn't show when @dates are used in the headline

* feat: add open app deeplink handler

* fix: database falling infinitely on mobile
This commit is contained in:
Lucas 2025-06-10 20:53:06 +08:00 committed by GitHub
parent 8d0d968e9b
commit ca8b4f9384
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 15 deletions

View File

@ -3,6 +3,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/dr
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:universal_platform/universal_platform.dart';
class SimpleColumnBlockWidthResizer extends StatefulWidget {
const SimpleColumnBlockWidthResizer({
@ -55,6 +56,10 @@ class _SimpleColumnBlockWidthResizerState
child: ValueListenableBuilder<bool>(
valueListenable: isHovering,
builder: (context, isHovering, child) {
if (UniversalPlatform.isMobile) {
return const SizedBox.shrink();
}
final hide = isDraggingAppFlowyEditorBlock.value || !isHovering;
return MouseRegion(
cursor: SystemMouseCursors.resizeLeftRight,

View File

@ -287,9 +287,6 @@ class OutlineItemWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final editorState = context.read<EditorState>();
final textStyle = editorState.editorStyle.textStyleConfiguration;
final style = textStyle.href.combine(textStyle.text);
return FlowyButton(
onTap: () => scrollToBlock(context),
text: Row(
@ -297,12 +294,7 @@ class OutlineItemWidget extends StatelessWidget {
children: [
HSpace(node.leftIndent),
Flexible(
child: Text(
node.outlineItemText,
textDirection: textDirection,
style: style,
overflow: TextOverflow.ellipsis,
),
child: buildOutlineItemWidget(context),
),
],
),
@ -320,6 +312,60 @@ class OutlineItemWidget extends StatelessWidget {
Position(path: node.path, offset: node.delta?.length ?? 0),
);
}
Widget buildOutlineItemWidget(BuildContext context) {
final editorState = context.read<EditorState>();
final textStyle = editorState.editorStyle.textStyleConfiguration;
final style = textStyle.href.combine(textStyle.text);
final textInserted = node.delta?.whereType<TextInsert>();
if (textInserted == null) {
return const SizedBox.shrink();
}
final children = <InlineSpan>[];
var i = 0;
for (final e in textInserted) {
final mentionAttribute = e.attributes?[MentionBlockKeys.mention];
final mention =
mentionAttribute is Map<String, dynamic> ? mentionAttribute : null;
final text = e.text;
if (mention != null) {
final type = mention[MentionBlockKeys.type];
children.add(
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: MentionBlock(
key: ValueKey(type),
node: node,
index: i,
mention: mention,
textStyle: style,
),
),
);
} else {
children.add(
TextSpan(
text: text,
style: style,
),
);
}
i += text.length;
}
return IgnorePointer(
child: Text.rich(
TextSpan(
children: children,
style: style,
),
),
);
}
}
extension on Node {
@ -339,8 +385,4 @@ extension on Node {
return 0.0;
}
String get outlineItemText {
return delta?.toPlainText() ?? '';
}
}

View File

@ -9,6 +9,7 @@ import 'package:appflowy/startup/tasks/deeplink/deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/expire_login_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/invitation_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/login_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/open_app_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/payment_deeplink_handler.dart';
import 'package:appflowy/user/application/auth/auth_error.dart';
import 'package:appflowy/user/application/user_auth_listener.dart';
@ -28,7 +29,8 @@ class AppFlowyCloudDeepLink {
..register(LoginDeepLinkHandler())
..register(PaymentDeepLinkHandler())
..register(InvitationDeepLinkHandler())
..register(ExpireLoginDeepLinkHandler());
..register(ExpireLoginDeepLinkHandler())
..register(OpenAppDeepLinkHandler());
_deepLinkSubscription = _AppLinkWrapper.instance.listen(
(Uri? uri) async {

View File

@ -0,0 +1,20 @@
import 'dart:async';
import 'package:appflowy/startup/tasks/deeplink/deeplink_handler.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
class OpenAppDeepLinkHandler extends DeepLinkHandler<void> {
@override
bool canHandle(Uri uri) {
return uri.toString() == 'appflowy-flutter://';
}
@override
Future<FlowyResult<void, FlowyError>> handle({
required Uri uri,
required DeepLinkStateHandler onStateChange,
}) async {
return FlowyResult.success(null);
}
}

View File

@ -1,6 +1,7 @@
import 'package:appflowy/startup/tasks/deeplink/deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/invitation_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/login_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/open_app_deeplink_handler.dart';
import 'package:appflowy/startup/tasks/deeplink/payment_deeplink_handler.dart';
import 'package:flutter_test/flutter_test.dart';
@ -9,7 +10,8 @@ void main() {
final deepLinkHandlerRegistry = DeepLinkHandlerRegistry.instance
..register(LoginDeepLinkHandler())
..register(PaymentDeepLinkHandler())
..register(InvitationDeepLinkHandler());
..register(InvitationDeepLinkHandler())
..register(OpenAppDeepLinkHandler());
test('invitation deep link handler', () {
final uri = Uri.parse(
@ -53,5 +55,10 @@ void main() {
},
);
});
test('open app deep link handler', () {
final uri = Uri.parse('appflowy-flutter://');
expect(OpenAppDeepLinkHandler().canHandle(uri), true);
});
});
}