diff --git a/lib/folder_views/note_tile.dart b/lib/folder_views/note_tile.dart index f34d7845..be513d24 100644 --- a/lib/folder_views/note_tile.dart +++ b/lib/folder_views/note_tile.dart @@ -11,6 +11,7 @@ class NoteTile extends StatelessWidget { final NoteSelectedFunction noteLongPressed; final bool selected; final String searchTerm; + final String searchTermLowerCase; NoteTile({ @required this.note, @@ -18,23 +19,11 @@ class NoteTile extends StatelessWidget { @required this.noteLongPressed, @required this.selected, @required this.searchTerm, - }); + }) : searchTermLowerCase = searchTerm.toLowerCase(); @override Widget build(BuildContext context) { - // FIXME: Make sure the text is in the body - var buffer = StringBuffer(); - var i = 0; - for (var line in LineSplitter.split(note.body)) { - line = replaceMarkdownChars(line); - buffer.writeln(line); - - i += 1; - if (i == 12) { - break; - } - } - var body = buffer.toString().trimRight(); + var body = _displayText(); var theme = Theme.of(context); var textTheme = theme.textTheme; @@ -67,14 +56,7 @@ class NoteTile extends StatelessWidget { const SizedBox(height: 8.0), Flexible( flex: 1, - // FIXME: Build a rich text with the text selected - child: Text( - body, - maxLines: 11, - overflow: TextOverflow.ellipsis, - style: textTheme.subtitle1 - .copyWith(fontSize: textTheme.subtitle1.fontSize * 0.90), - ), + child: _buildBody(context, body), ), ], crossAxisAlignment: CrossAxisAlignment.stretch, @@ -94,4 +76,79 @@ class NoteTile extends StatelessWidget { ), ); } + + static const _maxLines = 12; + + String _displayText() { + var foundSearchTerm = searchTerm.isEmpty ? true : false; + var buffer = []; + var i = 0; + + for (var line in LineSplitter.split(note.body)) { + line = replaceMarkdownChars(line); + buffer.add(line); + + if (line.toLowerCase().contains(searchTermLowerCase)) { + foundSearchTerm = true; + } + + i += 1; + if (i == _maxLines && foundSearchTerm) { + break; + } + } + + if (buffer.length > _maxLines) { + buffer = buffer.sublist(buffer.length - _maxLines); + } + + return buffer.join("\n").trimRight(); + } + + Widget _buildBody(BuildContext context, String text) { + var theme = Theme.of(context); + var textTheme = theme.textTheme; + var style = textTheme.subtitle1 + .copyWith(fontSize: textTheme.subtitle1.fontSize * 0.90); + + if (searchTerm.isEmpty) { + return Text( + text, + maxLines: _maxLines - 1, + overflow: TextOverflow.ellipsis, + style: style, + ); + } + + var i = text.toLowerCase().indexOf(searchTermLowerCase); + if (i == -1) { + return Text( + text, + maxLines: _maxLines - 1, + overflow: TextOverflow.ellipsis, + style: style, + ); + } + + var highlightStyle = textTheme.subtitle1.copyWith( + fontSize: textTheme.subtitle1.fontSize * 0.90, + backgroundColor: theme.highlightColor, + ); + + var before = text.substring(0, i); + var after = text.substring(i + searchTerm.length); + + return RichText( + text: TextSpan( + children: [ + TextSpan(text: before, style: style), + TextSpan( + text: searchTerm, + style: highlightStyle, + ), + TextSpan(text: after, style: style), + ], + ), + ); + } }