Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c2fa26a
fix: fix `_needsLayout`
sun-jiao Sep 14, 2023
6b91334
fix: wrap `SizedBox(child: IconButton())` as a function
sun-jiao Sep 14, 2023
601b961
Merge branch 'AppFlowy-IO:main' into find-replace-fix-1
sun-jiao Sep 15, 2023
4bedca4
chore: reformat files
sun-jiao Sep 15, 2023
bba13d2
Merge branch 'AppFlowy-IO:main' into find-replace-fix-1
sun-jiao Sep 15, 2023
6e67ced
feat: support regex and case sensitive in find and replace
sun-jiao Sep 16, 2023
40845a0
fix: remove `_rSearchMethod` because it is slightly slower than `all…
sun-jiao Sep 17, 2023
666f63d
feat: add 2 `SearchAlgorithm`s
sun-jiao Sep 17, 2023
e9121b9
fix: default caseSensitive is true
sun-jiao Sep 17, 2023
2fcbcad
test: add regex and case insensitive search test
sun-jiao Sep 17, 2023
44db679
chore: reformat file
sun-jiao Sep 17, 2023
20bd13a
fix: should be insensitive
sun-jiao Sep 17, 2023
58e7565
fix: update matches when `regex` or `caseSensitive` changed.
sun-jiao Sep 17, 2023
2d0d693
feat: change Range to Match
sun-jiao Sep 17, 2023
a342d98
Merge branch 'main' into find-replace-feat
sun-jiao Sep 17, 2023
9b2b2b0
chore: add "button" to button name
sun-jiao Sep 18, 2023
d7e84a2
Merge branch 'main' into find-replace-feat
sun-jiao Sep 18, 2023
77b3f5f
Merge branch 'main' into find-replace-feat
sun-jiao Sep 18, 2023
708eac3
fix: avoid creating too many instances
sun-jiao Sep 18, 2023
4b9bd28
chore: move throw error out of "else" branch
sun-jiao Sep 18, 2023
e324d5c
chore: rename method.
sun-jiao Sep 18, 2023
2caa385
Merge branch 'find-replace-feat' of https://github.com/sun-jiao/appfl…
sun-jiao Sep 18, 2023
e110509
chore: update comment
sun-jiao Sep 18, 2023
ff06b7d
chore: camel case
sun-jiao Sep 18, 2023
ab9f7b5
Merge branch 'AppFlowy-IO:main' into find-replace-feat
sun-jiao Sep 19, 2023
4181f00
feat: use dart built-in regex search
sun-jiao Sep 19, 2023
addea23
feat: add `regexFlag` and `caseSensitiveFlag`
sun-jiao Sep 19, 2023
7cab003
fix: use flags
sun-jiao Sep 19, 2023
7fd4d49
Merge branch 'main' into find-replace-feat
sun-jiao Sep 20, 2023
476888a
feat: extract icons
sun-jiao Sep 20, 2023
90368cd
chore: reformat file
sun-jiao Sep 21, 2023
d507155
Merge remote-tracking branch 'upstream/main' into find-replace-feat
sun-jiao Sep 21, 2023
d1ea4ab
test: add regex and case test case
sun-jiao Sep 21, 2023
16af1c3
chore: reformat test cases
sun-jiao Sep 21, 2023
97f067d
Merge branch 'AppFlowy-IO:main' into find-replace-feat
sun-jiao Sep 24, 2023
21f83fa
Merge branch 'AppFlowy-IO:main' into find-replace-feat
sun-jiao Sep 27, 2023
ee39de2
merge
sun-jiao Oct 4, 2023
4701db3
revert example
sun-jiao Oct 7, 2023
d35c4e8
Update search_service_v2.dart
sun-jiao Oct 7, 2023
0a53503
update to v2
sun-jiao Oct 7, 2023
8c69ea6
wrap match in MatchWrap
sun-jiao Oct 7, 2023
ac34ee2
rename it as SearchServiceV3, restore search service v1 and v2
sun-jiao Oct 7, 2023
e0f3921
chore: reformat files
sun-jiao Oct 7, 2023
484fd67
chore: typo
sun-jiao Oct 7, 2023
4a206b1
Merge branch 'AppFlowy-IO:main' into find-replace-feat
sun-jiao Oct 7, 2023
44033f2
chore: typo
sun-jiao Oct 7, 2023
cf9a2d4
Merge branch 'find-replace-feat' of https://github.com/sun-jiao/appfl…
sun-jiao Oct 7, 2023
4574659
chore: typo
sun-jiao Oct 7, 2023
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
51 changes: 51 additions & 0 deletions assets/images/case_sensitive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions assets/images/regex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions lib/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
"closeFind": "Close",
"replace": "Replace",
"replaceAll": "Replace all",
"regex": "Regex",
"caseSensitive": "Case sensitive",
"uploadImage": "Upload Image",
"urlImage": "URL Image",
"incorrectLink": "Incorrect Link",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/intl_zh_CN.arb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
"closeFind": "关闭",
"replace": "替换",
"replaceAll": "替换全部",
"regex": "正则表达式",
"caseSensitive": "区分大小写",
"uploadImage": "上传图片",
"urlImage": "网络图片",
"incorrectLink": "链接错误",
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/intl_zh_TW.arb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
"closeFind": "關閉",
"replace": "取代",
"replaceAll": "取代全部",
"regex": "正規表示式",
"caseSensitive": "區分大小寫",
"uploadImage": "上載圖片",
"urlImage": "網路圖片",
"incorrectLink": "連結錯誤",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ KeyEventResult _showFindAndReplaceDialog(
showReplaceMenu: openReplace,
localizations: localizations,
style: style,
showRegexButton: true,
showCaseSensitiveButton: true,
);

_findReplaceService?.show();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/editor/find_replace_menu/find_and_replace.dart
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export 'search_service_v2.dart';
export 'search_service_v3.dart' hide MatchWrapper;
6 changes: 6 additions & 0 deletions lib/src/editor/find_replace_menu/find_menu_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ class FindReplaceMenu implements FindReplaceService {
required this.showReplaceMenu,
this.localizations,
required this.style,
this.showRegexButton = true,
this.showCaseSensitiveButton = true,
});

final BuildContext context;
final EditorState editorState;
final bool showReplaceMenu;
final FindReplaceLocalizations? localizations;
final FindReplaceStyle style;
final bool showRegexButton;
final bool showCaseSensitiveButton;

final double topOffset = 52;
final double rightOffset = 40;
Expand Down Expand Up @@ -96,6 +100,8 @@ class FindReplaceMenu implements FindReplaceService {
showReplaceMenu: showReplaceMenu,
localizations: localizations,
style: style,
showRegexButton: showRegexButton,
showCaseSensitiveButton: showCaseSensitiveButton,
),
),
),
Expand Down
93 changes: 71 additions & 22 deletions lib/src/editor/find_replace_menu/find_replace_widget.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/find_replace_menu/find_replace_menu_icon_button.dart';
import 'find_replace_menu_icon_button.dart';
import 'package:flutter/material.dart';

const double _iconButtonSize = 30;
Expand All @@ -14,6 +14,8 @@ class FindAndReplaceMenuWidget extends StatefulWidget {
required this.editorState,
required this.showReplaceMenu,
required this.style,
this.showRegexButton = true,
this.showCaseSensitiveButton = true,
});

final EditorState editorState;
Expand All @@ -26,6 +28,8 @@ class FindAndReplaceMenuWidget extends StatefulWidget {
///
/// only works for SearchService, not for SearchServiceV2
final FindReplaceStyle style;
final bool showRegexButton;
final bool showCaseSensitiveButton;

/// The localizations of the find and replace menu
final FindReplaceLocalizations? localizations;
Expand All @@ -42,15 +46,25 @@ class FindAndReplaceMenuWidget extends StatefulWidget {
}

class _FindAndReplaceMenuWidgetState extends State<FindAndReplaceMenuWidget> {
final focusNode = FocusNode();
final replaceFocusNode = FocusNode();
final findController = TextEditingController();
final replaceController = TextEditingController();
String queriedPattern = '';
bool showRegexButton = true;
bool showCaseSensitiveButton = true;
bool showReplaceMenu = false;

late SearchServiceV2 searchService = SearchServiceV2(
late SearchServiceV3 searchService = SearchServiceV3(
editorState: widget.editorState,
);

@override
void initState() {
super.initState();
showReplaceMenu = widget.showReplaceMenu;
showRegexButton = widget.showRegexButton;
showCaseSensitiveButton = widget.showCaseSensitiveButton;

showReplaceMenu = widget.showReplaceMenu;
}
Expand Down Expand Up @@ -106,6 +120,8 @@ class FindMenu extends StatefulWidget {
required this.style,
required this.searchService,
required this.onShowReplace,
this.showRegexButton = true,
this.showCaseSensitiveButton = true,
});

final EditorState editorState;
Expand All @@ -128,9 +144,12 @@ class FindMenu extends StatefulWidget {
/// Whether to show the replace menu or not
final bool showReplaceMenu;

final bool showRegexButton;
final bool showCaseSensitiveButton;

final void Function(bool showReplaceMenu) onShowReplace;

final SearchServiceV2 searchService;
final SearchServiceV3 searchService;

@override
State<FindMenu> createState() => _FindMenuState();
Expand All @@ -146,14 +165,20 @@ class _FindMenuState extends State<FindMenu> {
bool showReplaceMenu = false;
bool caseSensitive = false;

bool showRegexButton = true;
bool showCaseSensitiveButton = true;

@override
void initState() {
super.initState();

showReplaceMenu = widget.showReplaceMenu;
caseSensitive = widget.caseSensitive;

widget.searchService.matchedPositions.addListener(_setState);
showRegexButton = widget.showRegexButton;
showCaseSensitiveButton = widget.showCaseSensitiveButton;

widget.searchService.matchWrappers.addListener(_setState);
widget.searchService.currentSelectedIndex.addListener(_setState);

findTextEditingController.addListener(_searchPattern);
Expand All @@ -165,7 +190,7 @@ class _FindMenuState extends State<FindMenu> {

@override
void dispose() {
widget.searchService.matchedPositions.removeListener(_setState);
widget.searchService.matchWrappers.removeListener(_setState);
widget.searchService.currentSelectedIndex.removeListener(_setState);
widget.searchService.dispose();
findTextEditingController.removeListener(_searchPattern);
Expand All @@ -178,7 +203,7 @@ class _FindMenuState extends State<FindMenu> {
Widget build(BuildContext context) {
// the selectedIndex from searchService is 0-based
final selectedIndex = widget.searchService.selectedIndex + 1;
final matches = widget.searchService.matchedPositions.value;
final matches = widget.searchService.matchWrappers.value;
return Row(
children: [
// expand/collapse button
Expand Down Expand Up @@ -230,21 +255,6 @@ class _FindMenuState extends State<FindMenu> {
: '$selectedIndex of ${matches.length}',
),
),
// case sensitive button
DecoratedBox(
decoration: BoxDecoration(
color: caseSensitive ? Colors.blue.shade400 : Colors.transparent,
borderRadius: BorderRadius.circular(0.0),
),
child: FindAndReplaceMenuIconButton(
onPressed: () => setState(() {
caseSensitive = !caseSensitive;
widget.searchService.caseSensitive = caseSensitive;
}),
icon: const Icon(Icons.keyboard_capslock),
tooltip: 'Aa',
),
),
// previous match button
FindAndReplaceMenuIconButton(
iconButtonKey: const Key('previousMatchButton'),
Expand All @@ -268,6 +278,45 @@ class _FindMenuState extends State<FindMenu> {
tooltip: widget.localizations?.close ??
AppFlowyEditorLocalizations.current.closeFind,
),
// regex button
if (showRegexButton)
FindAndReplaceMenuIconButton(
key: const Key('findRegexButton'),
onPressed: () {
setState(() {
widget.searchService.regex = !widget.searchService.regex;
});
_searchPattern();
},
icon: EditorSvg(
name: 'regex',
width: 20,
height: 20,
color: widget.searchService.regex ? Colors.black : Colors.grey,
),
tooltip: AppFlowyEditorLocalizations.current.regex,
),
// case sensitive button
if (showCaseSensitiveButton)
FindAndReplaceMenuIconButton(
key: const Key('caseSensitiveButton'),
onPressed: () {
setState(() {
widget.searchService.caseSensitive =
!widget.searchService.caseSensitive;
});
_searchPattern();
},
icon: EditorSvg(
name: 'case_sensitive',
width: 20,
height: 20,
color: widget.searchService.caseSensitive
? Colors.black
: Colors.grey,
),
tooltip: AppFlowyEditorLocalizations.current.caseSensitive,
),
],
);
}
Expand Down Expand Up @@ -298,7 +347,7 @@ class ReplaceMenu extends StatefulWidget {
/// The localizations of the find and replace menu
final FindReplaceLocalizations? localizations;

final SearchServiceV2 searchService;
final SearchServiceV3 searchService;

@override
State<ReplaceMenu> createState() => _ReplaceMenuState();
Expand Down
Loading