Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Chat-ng]: Appflowy Editor editor integration #2332

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/2332-chat-ng-editor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Chat-NG now supports Appflowy editor with proper markdown support. Some/Other features might be disabled or limited for now.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Chat-NG now supports Appflowy editor with proper markdown support. Some/Other features might be disabled or limited for now.
- [Labs] Chat-NG now offers a fresh new WYSIWYG editor. More features upcoming.

2 changes: 1 addition & 1 deletion app/integration_test/tests/pins.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:acter/common/utils/constants.dart';
import 'package:acter/common/widgets/html_editor.dart';
import 'package:acter/common/widgets/html_editor/html_editor.dart';
import 'package:acter/common/widgets/spaces/select_space_form_field.dart';
import 'package:acter/features/home/data/keys.dart';
import 'package:acter/features/pins/pages/create_pin_page.dart';
Expand Down
2 changes: 1 addition & 1 deletion app/lib/common/widgets/edit_html_description_sheet.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:acter/common/themes/colors/color_scheme.dart';
import 'package:acter/common/toolkit/buttons/primary_action_button.dart';
import 'package:acter/common/widgets/html_editor.dart';
import 'package:acter/common/widgets/html_editor/html_editor.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
Expand Down
112 changes: 112 additions & 0 deletions app/lib/common/widgets/html_editor/components/mention_block.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import 'package:acter/common/widgets/html_editor/components/mention_content.dart';
import 'package:acter/common/widgets/html_editor/models/mention_block_keys.dart';
import 'package:acter/common/widgets/html_editor/models/mention_type.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

class MentionBlock extends StatelessWidget {
const MentionBlock({
super.key,
required this.editorState,
required this.mention,
required this.node,
required this.index,
required this.textStyle,
});

final EditorState editorState;
final Map<String, dynamic> mention;
final Node node;
final int index;
final TextStyle? textStyle;

@override
Widget build(BuildContext context) {
final type = MentionType.fromStr(mention[MentionBlockKeys.type]);

switch (type) {
case MentionType.user:
final String? userId = mention[MentionBlockKeys.userId] as String?;
final String? blockId = mention[MentionBlockKeys.blockId] as String?;
final String? displayName =
mention[MentionBlockKeys.displayName] as String?;

if (userId == null) {
return const SizedBox.shrink();
}

return _mentionContent(
context: context,
mentionId: userId,
blockId: blockId,
editorState: editorState,
displayName: displayName,
node: node,
index: index,
);
case MentionType.room:
final String? roomId = mention[MentionBlockKeys.roomId] as String?;
final String? blockId = mention[MentionBlockKeys.blockId] as String?;
final String? displayName =
mention[MentionBlockKeys.displayName] as String?;

if (roomId == null) {
return const SizedBox.shrink();
}

return _mentionContent(
context: context,
mentionId: roomId,
blockId: blockId,
editorState: editorState,
displayName: displayName,
node: node,
index: index,
);
default:
return const SizedBox.shrink();
}
}

Widget _mentionContent({
required BuildContext context,
required EditorState editorState,
required String mentionId,
String? blockId,
required String? displayName,
gtalha07 marked this conversation as resolved.
Show resolved Hide resolved
TextStyle? textStyle,
gtalha07 marked this conversation as resolved.
Show resolved Hide resolved
required Node node,
required int index,
}) {
final desktopPlatforms = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mouse can also be plugged/connected to phones. don't do a check like that.

TargetPlatform.linux,
TargetPlatform.macOS,
TargetPlatform.windows,
];
final mentionContentWidget = MentionContentWidget(
mentionId: mentionId,
displayName: displayName,
textStyle: textStyle,
editorState: editorState,
node: node,
index: index,
);

final Widget content = GestureDetector(
onTap: _handleUserTap,
behavior: HitTestBehavior.opaque,
child: desktopPlatforms.contains(Theme.of(context).platform)
? MouseRegion(
cursor: SystemMouseCursors.click,
child: mentionContentWidget,
)
: mentionContentWidget,
);

return content;
}

void _handleUserTap() {
// Implement user tap action (e.g., show profile, start chat)
}
}
50 changes: 50 additions & 0 deletions app/lib/common/widgets/html_editor/components/mention_content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

class MentionContentWidget extends StatelessWidget {
gtalha07 marked this conversation as resolved.
Show resolved Hide resolved
const MentionContentWidget({
super.key,
required this.mentionId,
this.displayName,
required this.textStyle,
required this.editorState,
required this.node,
required this.index,
});

final String mentionId;
final String? displayName;
final TextStyle? textStyle;
final EditorState editorState;
final Node node;
final int index;

@override
Widget build(BuildContext context) {
final baseTextStyle = textStyle?.copyWith(
color: Theme.of(context).colorScheme.primary,
leadingDistribution: TextLeadingDistribution.even,
);
gtalha07 marked this conversation as resolved.
Show resolved Hide resolved

return Row(
mainAxisSize: MainAxisSize.min,
children: [
if (displayName != null)
Text(
displayName!,
style: baseTextStyle?.copyWith(
fontWeight: FontWeight.w500,
),
gtalha07 marked this conversation as resolved.
Show resolved Hide resolved
),
const SizedBox(width: 4),
Text(
mentionId,
style: baseTextStyle?.copyWith(
fontSize: (baseTextStyle.fontSize ?? 14.0) * 0.9,
color: Theme.of(context).hintColor,
),
),
],
);
}
}
Loading
Loading