Skip to content

Commit

Permalink
fix: count title towards word count(#7042)
Browse files Browse the repository at this point in the history
  • Loading branch information
asjqkkkk committed Jan 3, 2025
1 parent c05f19e commit 5ddac9e
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/view_meta_info.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:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

Expand Down Expand Up @@ -31,4 +37,104 @@ void main() {
expect(pageFinder, findsNWidgets(1));
});
});

testWidgets('count title towards word count', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent();

Finder title = tester.editor.findDocumentTitle('');

await tester.openMoreViewActions();
final viewMetaInfo = find.byType(ViewMetaInfo);
expect(viewMetaInfo, findsOneWidget);

ViewMetaInfo viewMetaInfoWidget =
viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
Counters titleCounter = viewMetaInfoWidget.titleCounters!;

expect(titleCounter.charCount, 0);
expect(titleCounter.wordCount, 0);

/// input [str1] within title
const str1 = 'Hello',
str2 = '$str1 AppFlowy',
str3 = '$str2!',
str4 = 'Hello world';
await tester.simulateKeyEvent(LogicalKeyboardKey.escape);
await tester.tapButton(title);
await tester.enterText(title, str1);
await tester.pumpAndSettle(const Duration(seconds: 1));
await tester.openMoreViewActions();
viewMetaInfoWidget = viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
titleCounter = viewMetaInfoWidget.titleCounters!;
expect(titleCounter.charCount, str1.length);
expect(titleCounter.wordCount, 1);

/// input [str2] within title
title = tester.editor.findDocumentTitle(str1);
await tester.simulateKeyEvent(LogicalKeyboardKey.escape);
await tester.tapButton(title);
await tester.enterText(title, str2);
await tester.pumpAndSettle(const Duration(seconds: 1));
await tester.openMoreViewActions();
viewMetaInfoWidget = viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
titleCounter = viewMetaInfoWidget.titleCounters!;
expect(titleCounter.charCount, str2.length);
expect(titleCounter.wordCount, 2);

/// input [str3] within title
title = tester.editor.findDocumentTitle(str2);
await tester.simulateKeyEvent(LogicalKeyboardKey.escape);
await tester.tapButton(title);
await tester.enterText(title, str3);
await tester.pumpAndSettle(const Duration(seconds: 1));
await tester.openMoreViewActions();
viewMetaInfoWidget = viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
titleCounter = viewMetaInfoWidget.titleCounters!;
expect(titleCounter.charCount, str3.length);
expect(titleCounter.wordCount, 2);

/// input [str4] within document
await tester.simulateKeyEvent(LogicalKeyboardKey.escape);
await tester.editor
.updateSelection(Selection.collapsed(Position(path: [0])));
await tester.pumpAndSettle();
await tester.editor
.getCurrentEditorState()
.insertTextAtCurrentSelection(str4);
await tester.pumpAndSettle(const Duration(seconds: 1));
await tester.openMoreViewActions();
final texts =
find.descendant(of: viewMetaInfo, matching: find.byType(FlowyText));
expect(texts, findsNWidgets(3));
viewMetaInfoWidget = viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
titleCounter = viewMetaInfoWidget.titleCounters!;
final Counters documentCounters = viewMetaInfoWidget.documentCounters!;
final wordCounter = texts.evaluate().elementAt(0).widget as FlowyText,
charCounter = texts.evaluate().elementAt(1).widget as FlowyText;
final numberFormat = NumberFormat();
expect(
wordCounter.text,
LocaleKeys.moreAction_wordCount.tr(
args: [
numberFormat
.format(titleCounter.wordCount + documentCounters.wordCount)
.toString(),
],
),
);
expect(
charCounter.text,
LocaleKeys.moreAction_charCount.tr(
args: [
numberFormat
.format(
titleCounter.charCount + documentCounters.charCount,
)
.toString(),
],
),
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:appflowy/plugins/document/presentation/editor_style.dart';
import 'package:appflowy/shared/text_field/text_filed_with_metric_lines.dart';
import 'package:appflowy/workspace/application/appearance_defaults.dart';
import 'package:appflowy/workspace/application/view/view_bloc.dart';
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
Expand Down Expand Up @@ -220,6 +221,9 @@ class _InnerCoverTitleState extends State<_InnerCoverTitle> {
.read<ViewBloc>()
.add(ViewEvent.rename(titleTextController.text));
}
context
.read<ViewInfoBloc?>()
?.add(ViewInfoEvent.titleChanged(titleTextController.text));
},
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ final numberedListRegex = RegExp(_numberedListPattern);

const _localPathPattern = r'^(file:\/\/|\/|\\|[a-zA-Z]:[/\\]|\.{1,2}[/\\])';
final localPathRegex = RegExp(_localPathPattern, caseSensitive: false);

const _wordPattern = r"\S+";
final wordRegex = RegExp(_wordPattern);
8 changes: 8 additions & 0 deletions frontend/appflowy_flutter/lib/util/string_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,11 @@ extension IconExtension on String {
)..iconGroup = iconGroup;
}
}

extension CounterExtension on String {
Counters getCounter() {
final wordCount = wordRegex.allMatches(this).length;
final charCount = runes.length;
return Counters(wordCount: wordCount, charCount: charCount);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy/util/int64_extension.dart';
import 'package:appflowy/util/string_extension.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:bloc/bloc.dart';
Expand All @@ -11,7 +12,12 @@ class ViewInfoBloc extends Bloc<ViewInfoEvent, ViewInfoState> {
on<ViewInfoEvent>((event, emit) {
event.when(
started: () {
emit(state.copyWith(createdAt: view.createTime.toDateTime()));
emit(
state.copyWith(
createdAt: view.createTime.toDateTime(),
titleCounters: view.name.getCounter(),
),
);
},
unregisterEditorState: () {
_clearWordCountService();
Expand All @@ -36,6 +42,13 @@ class ViewInfoBloc extends Bloc<ViewInfoEvent, ViewInfoState> {
),
);
},
titleChanged: (s) {
emit(
state.copyWith(
titleCounters: s.getCounter(),
),
);
},
);
});
}
Expand Down Expand Up @@ -71,17 +84,21 @@ class ViewInfoEvent with _$ViewInfoEvent {
}) = _RegisterEditorState;

const factory ViewInfoEvent.wordCountChanged() = _WordCountChanged;

const factory ViewInfoEvent.titleChanged(String title) = _TitleChanged;
}

@freezed
class ViewInfoState with _$ViewInfoState {
const factory ViewInfoState({
required Counters? documentCounters,
required Counters? titleCounters,
required DateTime? createdAt,
}) = _ViewInfoState;

factory ViewInfoState.initial() => const ViewInfoState(
documentCounters: null,
titleCounters: null,
createdAt: null,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class _MoreViewActionsState extends State<MoreViewActions> {
dateFormat: dateFormat,
timeFormat: timeFormat,
documentCounters: state.documentCounters,
titleCounters: state.titleCounters,
createdAt: state.createdAt,
),
const VSpace(4.0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ class ViewMetaInfo extends StatelessWidget {
required this.dateFormat,
required this.timeFormat,
this.documentCounters,
this.titleCounters,
this.createdAt,
});

final UserDateFormatPB dateFormat;
final UserTimeFormatPB timeFormat;
final Counters? documentCounters;
final Counters? titleCounters;
final DateTime? createdAt;

@override
Expand All @@ -31,11 +33,15 @@ class ViewMetaInfo extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (documentCounters != null) ...[
if (documentCounters != null && titleCounters != null) ...[
FlowyText.regular(
LocaleKeys.moreAction_wordCount.tr(
args: [
numberFormat.format(documentCounters!.wordCount).toString(),
numberFormat
.format(
documentCounters!.wordCount + titleCounters!.wordCount,
)
.toString(),
],
),
fontSize: 12,
Expand All @@ -45,15 +51,20 @@ class ViewMetaInfo extends StatelessWidget {
FlowyText.regular(
LocaleKeys.moreAction_charCount.tr(
args: [
numberFormat.format(documentCounters!.charCount).toString(),
numberFormat
.format(
documentCounters!.charCount + titleCounters!.charCount,
)
.toString(),
],
),
fontSize: 12,
color: Theme.of(context).hintColor,
),
],
if (createdAt != null) ...[
if (documentCounters != null) const VSpace(2),
if (documentCounters != null && titleCounters != null)
const VSpace(2),
FlowyText.regular(
LocaleKeys.moreAction_createdAt.tr(
args: [dateFormat.formatDate(createdAt!, true, timeFormat)],
Expand Down

0 comments on commit 5ddac9e

Please sign in to comment.