From 9bf9193ec8c1ca8d25fdf58aa649ab3f365e638e Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Fri, 13 Nov 2020 16:03:28 +0100 Subject: [PATCH] RepoSelector: Hilight selected text --- lib/setup/repo_selector.dart | 26 ++++++++++++++++- lib/widgets/highlighted_text.dart | 48 +++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lib/setup/repo_selector.dart b/lib/setup/repo_selector.dart index b7669bc7..5138cf8c 100644 --- a/lib/setup/repo_selector.dart +++ b/lib/setup/repo_selector.dart @@ -14,6 +14,7 @@ import 'package:gitjournal/setup/button.dart'; import 'package:gitjournal/setup/error.dart'; import 'package:gitjournal/setup/loading.dart'; import 'package:gitjournal/utils/logger.dart'; +import 'package:gitjournal/widgets/highlighted_text.dart'; //import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -139,6 +140,7 @@ class GitHostSetupRepoSelectorState extends State { for (var repo in filteredRepos) _RepoTile( repo: repo, + searchText: q, onTap: () { setState(() { selectedRepo = repo; @@ -241,11 +243,13 @@ class GitHostSetupRepoSelectorState extends State { class _RepoTile extends StatelessWidget { final GitHostRepo repo; + final String searchText; final Function onTap; final bool selected; _RepoTile({ @required this.repo, + @required this.searchText, @required this.onTap, @required this.selected, }); @@ -291,8 +295,28 @@ class _RepoTile extends StatelessWidget { ), ); */ + var style = Theme.of(context).textTheme.subtitle1; + + Widget title = Text(repo.fullName, style: style); + if (searchText.isNotEmpty) { + title = title = RichText( + text: TextSpan( + children: [ + TextSpan(text: repo.username + '/', style: style), + ...HighlightTextSpan( + text: repo.name, + highlightText: searchText, + highlightTextLowerCase: searchText, + style: style, + highlightStyle: style.copyWith(fontWeight: FontWeight.bold), + ).build(context), + ], + ), + ); + } + return ListTile( - title: Text(repo.fullName), + title: title, trailing: _SmartDateTime(repo.updatedAt, textTheme.caption), selected: selected, contentPadding: const EdgeInsets.all(0.0), diff --git a/lib/widgets/highlighted_text.dart b/lib/widgets/highlighted_text.dart index 7ba8abda..3d08e95b 100644 --- a/lib/widgets/highlighted_text.dart +++ b/lib/widgets/highlighted_text.dart @@ -6,6 +6,7 @@ class HighlightedText extends StatelessWidget { final String highlightTextLowerCase; final TextStyle style; + final TextStyle highlightStyle; final TextOverflow overflow; final int maxLines; @@ -14,6 +15,7 @@ class HighlightedText extends StatelessWidget { @required this.highlightText, @required this.highlightTextLowerCase, @required this.style, + this.highlightStyle, this.overflow, this.maxLines, }); @@ -29,9 +31,10 @@ class HighlightedText extends StatelessWidget { return Text(text, maxLines: maxLines, overflow: overflow, style: style); } - var highlightStyle = style.copyWith( - backgroundColor: Theme.of(context).highlightColor, - ); + var highlightStyle = this.highlightStyle ?? + style.copyWith( + backgroundColor: Theme.of(context).highlightColor, + ); var before = text.substring(0, i); var term = text.substring(i, i + highlightText.length); @@ -49,3 +52,42 @@ class HighlightedText extends StatelessWidget { ); } } + +class HighlightTextSpan { + final String text; + final String highlightText; + final String highlightTextLowerCase; + + final TextStyle style; + final TextStyle highlightStyle; + + HighlightTextSpan({ + @required this.text, + @required this.highlightText, + @required this.highlightTextLowerCase, + @required this.style, + this.highlightStyle, + }); + + List build(BuildContext context) { + var i = text.toLowerCase().indexOf(highlightTextLowerCase); + if (i == -1) { + return []; + } + + var highlightStyle = this.highlightStyle ?? + style.copyWith( + backgroundColor: Theme.of(context).highlightColor, + ); + + var before = text.substring(0, i); + var term = text.substring(i, i + highlightText.length); + var after = text.substring(i + highlightText.length); + + return [ + TextSpan(text: before, style: style), + TextSpan(text: term, style: highlightStyle), + TextSpan(text: after, style: style), + ]; + } +}