Skip to content

Commit d34ade2

Browse files
committed
fix: count title towards word count(#7042)
1 parent c05f19e commit d34ade2

File tree

5 files changed

+82
-5
lines changed

5 files changed

+82
-5
lines changed

frontend/appflowy_flutter/integration_test/desktop/document/document_more_actions_test.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
2+
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/view_meta_info.dart';
3+
import 'package:appflowy_editor/appflowy_editor.dart';
4+
import 'package:flutter/services.dart';
25
import 'package:flutter_test/flutter_test.dart';
36
import 'package:integration_test/integration_test.dart';
47

@@ -31,4 +34,37 @@ void main() {
3134
expect(pageFinder, findsNWidgets(1));
3235
});
3336
});
37+
38+
testWidgets('count title towards word count', (tester) async {
39+
await tester.initializeAppFlowy();
40+
await tester.tapAnonymousSignInButton();
41+
await tester.createNewPageWithNameUnderParent();
42+
43+
final title = tester.editor.findDocumentTitle('');
44+
45+
await tester.openMoreViewActions();
46+
Finder viewMetaInfo = find.byType(ViewMetaInfo);
47+
expect(viewMetaInfo, findsOneWidget);
48+
49+
ViewMetaInfo viewMetaInfoWidget =
50+
viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
51+
Counters titleCounter = viewMetaInfoWidget.titleCounters!;
52+
53+
expect(titleCounter.charCount, 0);
54+
expect(titleCounter.wordCount, 0);
55+
56+
/// input [titleString] within title
57+
const titleString = 'Title';
58+
await tester.tapButton(title);
59+
await simulateKeyDownEvent(LogicalKeyboardKey.escape);
60+
await tester.pumpAndSettle();
61+
await tester.enterText(title, titleString);
62+
await tester.pumpAndSettle(const Duration(seconds: 1));
63+
await tester.openMoreViewActions();
64+
viewMetaInfo = find.byType(ViewMetaInfo);
65+
viewMetaInfoWidget = viewMetaInfo.evaluate().first.widget as ViewMetaInfo;
66+
titleCounter = viewMetaInfoWidget.titleCounters!;
67+
expect(titleCounter.charCount, titleString.length);
68+
expect(titleCounter.wordCount, 1);
69+
});
3470
}

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/cover_title.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:appflowy/plugins/document/presentation/editor_style.dart';
55
import 'package:appflowy/shared/text_field/text_filed_with_metric_lines.dart';
66
import 'package:appflowy/workspace/application/appearance_defaults.dart';
77
import 'package:appflowy/workspace/application/view/view_bloc.dart';
8+
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
89
import 'package:appflowy_backend/log.dart';
910
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
1011
import 'package:appflowy_editor/appflowy_editor.dart';
@@ -220,6 +221,13 @@ class _InnerCoverTitleState extends State<_InnerCoverTitle> {
220221
.read<ViewBloc>()
221222
.add(ViewEvent.rename(titleTextController.text));
222223
}
224+
try {
225+
context
226+
.read<ViewInfoBloc>()
227+
.add(ViewInfoEvent.titleChanged(titleTextController.text));
228+
} catch (e) {
229+
Log.error('read ViewInfoBloc error', e);
230+
}
223231
},
224232
);
225233
}

frontend/appflowy_flutter/lib/workspace/application/view_info/view_info_bloc.dart

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ class ViewInfoBloc extends Bloc<ViewInfoEvent, ViewInfoState> {
1111
on<ViewInfoEvent>((event, emit) {
1212
event.when(
1313
started: () {
14-
emit(state.copyWith(createdAt: view.createTime.toDateTime()));
14+
emit(
15+
state.copyWith(
16+
createdAt: view.createTime.toDateTime(),
17+
titleCounters: _getTitleCounter(view.name),
18+
),
19+
);
1520
},
1621
unregisterEditorState: () {
1722
_clearWordCountService();
@@ -36,6 +41,13 @@ class ViewInfoBloc extends Bloc<ViewInfoEvent, ViewInfoState> {
3641
),
3742
);
3843
},
44+
titleChanged: (s) {
45+
emit(
46+
state.copyWith(
47+
titleCounters: _getTitleCounter(s),
48+
),
49+
);
50+
},
3951
);
4052
});
4153
}
@@ -58,6 +70,12 @@ class ViewInfoBloc extends Bloc<ViewInfoEvent, ViewInfoState> {
5870
..dispose();
5971
_wordCountService = null;
6072
}
73+
74+
Counters _getTitleCounter(String title) {
75+
final wordCount = RegExp(r"\S+").allMatches(title).length;
76+
final charCount = title.runes.length;
77+
return Counters(wordCount: wordCount, charCount: charCount);
78+
}
6179
}
6280

6381
@freezed
@@ -71,17 +89,21 @@ class ViewInfoEvent with _$ViewInfoEvent {
7189
}) = _RegisterEditorState;
7290

7391
const factory ViewInfoEvent.wordCountChanged() = _WordCountChanged;
92+
93+
const factory ViewInfoEvent.titleChanged(String title) = _TitleChanged;
7494
}
7595

7696
@freezed
7797
class ViewInfoState with _$ViewInfoState {
7898
const factory ViewInfoState({
7999
required Counters? documentCounters,
100+
required Counters? titleCounters,
80101
required DateTime? createdAt,
81102
}) = _ViewInfoState;
82103

83104
factory ViewInfoState.initial() => const ViewInfoState(
84105
documentCounters: null,
106+
titleCounters: null,
85107
createdAt: null,
86108
);
87109
}

frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class _MoreViewActionsState extends State<MoreViewActions> {
129129
dateFormat: dateFormat,
130130
timeFormat: timeFormat,
131131
documentCounters: state.documentCounters,
132+
titleCounters: state.titleCounters,
132133
createdAt: state.createdAt,
133134
),
134135
const VSpace(4.0),

frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/widgets/view_meta_info.dart

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ class ViewMetaInfo extends StatelessWidget {
1313
required this.dateFormat,
1414
required this.timeFormat,
1515
this.documentCounters,
16+
this.titleCounters,
1617
this.createdAt,
1718
});
1819

1920
final UserDateFormatPB dateFormat;
2021
final UserTimeFormatPB timeFormat;
2122
final Counters? documentCounters;
23+
final Counters? titleCounters;
2224
final DateTime? createdAt;
2325

2426
@override
@@ -31,11 +33,15 @@ class ViewMetaInfo extends StatelessWidget {
3133
child: Column(
3234
crossAxisAlignment: CrossAxisAlignment.start,
3335
children: [
34-
if (documentCounters != null) ...[
36+
if (documentCounters != null && titleCounters != null) ...[
3537
FlowyText.regular(
3638
LocaleKeys.moreAction_wordCount.tr(
3739
args: [
38-
numberFormat.format(documentCounters!.wordCount).toString(),
40+
numberFormat
41+
.format(
42+
documentCounters!.wordCount + titleCounters!.wordCount,
43+
)
44+
.toString(),
3945
],
4046
),
4147
fontSize: 12,
@@ -45,14 +51,18 @@ class ViewMetaInfo extends StatelessWidget {
4551
FlowyText.regular(
4652
LocaleKeys.moreAction_charCount.tr(
4753
args: [
48-
numberFormat.format(documentCounters!.charCount).toString(),
54+
numberFormat
55+
.format(
56+
documentCounters!.charCount + titleCounters!.charCount,
57+
)
58+
.toString(),
4959
],
5060
),
5161
fontSize: 12,
5262
color: Theme.of(context).hintColor,
5363
),
5464
],
55-
if (createdAt != null) ...[
65+
if (createdAt != null && titleCounters != null) ...[
5666
if (documentCounters != null) const VSpace(2),
5767
FlowyText.regular(
5868
LocaleKeys.moreAction_createdAt.tr(

0 commit comments

Comments
 (0)