Browse Source

perf(neon_news): do not use the spread operator for building lists

Signed-off-by: Nikolas Rimikis <leptopoda@users.noreply.github.com>
pull/1094/head
Nikolas Rimikis 1 year ago
parent
commit
4f4e161063
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 25
      packages/neon/neon_news/lib/dialogs/add_feed.dart
  2. 4
      packages/neon/neon_news/lib/pages/article.dart
  3. 46
      packages/neon/neon_news/lib/widgets/articles_view.dart
  4. 236
      packages/neon/neon_news/lib/widgets/feeds_view.dart
  5. 27
      packages/neon/neon_notes/lib/dialogs/create_note.dart

25
packages/neon/neon_news/lib/dialogs/add_feed.dart

@ -71,30 +71,29 @@ class _NewsAddFeedDialogState extends State<NewsAddFeedDialog> {
submit(); submit();
}, },
), ),
if (widget.folderID == null) ...[ if (widget.folderID == null && folders.hasError)
Center( Center(
child: NeonError( child: NeonError(
folders.error, folders.error,
onRetry: widget.bloc.refresh, onRetry: widget.bloc.refresh,
), ),
), ),
if (widget.folderID == null)
Center( Center(
child: NeonLinearProgressIndicator( child: NeonLinearProgressIndicator(
visible: folders.isLoading, visible: folders.isLoading,
), ),
), ),
if (folders.hasData) ...[ if (widget.folderID == null && folders.hasData)
NewsFolderSelect( NewsFolderSelect(
folders: folders.requireData, folders: folders.requireData,
value: folder, value: folder,
onChanged: (final f) { onChanged: (final f) {
setState(() { setState(() {
folder = f; folder = f;
}); });
}, },
), ),
],
],
ElevatedButton( ElevatedButton(
onPressed: folders.hasData ? submit : null, onPressed: folders.hasData ? submit : null,
child: Text(NewsLocalizations.of(context).feedAdd), child: Text(NewsLocalizations.of(context).feedAdd),

4
packages/neon/neon_news/lib/pages/article.dart

@ -146,7 +146,7 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
); );
}, },
), ),
if (widget.url != null) ...[ if (widget.url != null)
IconButton( IconButton(
onPressed: () async { onPressed: () async {
await launchUrlString( await launchUrlString(
@ -157,6 +157,7 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
tooltip: NewsLocalizations.of(context).articleOpenLink, tooltip: NewsLocalizations.of(context).articleOpenLink,
icon: const Icon(Icons.open_in_new), icon: const Icon(Icons.open_in_new),
), ),
if (widget.url != null)
IconButton( IconButton(
onPressed: () async { onPressed: () async {
await Share.share(await _getURL()); await Share.share(await _getURL());
@ -164,7 +165,6 @@ class _NewsArticlePageState extends State<NewsArticlePage> {
tooltip: NewsLocalizations.of(context).articleShare, tooltip: NewsLocalizations.of(context).articleShare,
icon: const Icon(Icons.share), icon: const Icon(Icons.share),
), ),
],
], ],
), ),
body: SafeArea( body: SafeArea(

46
packages/neon/neon_news/lib/widgets/articles_view.dart

@ -63,30 +63,20 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
isExpanded: true, isExpanded: true,
value: selectedFilterTypeSnapshot.data, value: selectedFilterTypeSnapshot.data,
items: [ items: [
FilterType.all, _buildDropdownItem(
FilterType.unread, FilterType.all,
if (widget.bloc.listType == null) ...[ NewsLocalizations.of(context).articlesFilterAll,
FilterType.starred, ),
], _buildDropdownItem(
].map<DropdownMenuItem<FilterType>>( FilterType.unread,
(final a) { NewsLocalizations.of(context).articlesFilterUnread,
late final String label; ),
switch (a) { if (widget.bloc.listType == null)
case FilterType.all: _buildDropdownItem(
label = NewsLocalizations.of(context).articlesFilterAll; FilterType.starred,
case FilterType.unread: NewsLocalizations.of(context).articlesFilterStarred,
label = NewsLocalizations.of(context).articlesFilterUnread; ),
case FilterType.starred: ],
label = NewsLocalizations.of(context).articlesFilterStarred;
default:
throw Exception('FilterType $a should not be shown');
}
return DropdownMenuItem(
value: a,
child: Text(label),
);
},
).toList(),
onChanged: (final value) { onChanged: (final value) {
widget.bloc.setFilterType(value!); widget.bloc.setFilterType(value!);
}, },
@ -99,6 +89,11 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
), ),
); );
DropdownMenuItem<FilterType> _buildDropdownItem(final FilterType value, final String label) => DropdownMenuItem(
value: value,
child: Text(label),
);
Widget _buildArticle( Widget _buildArticle(
final BuildContext context, final BuildContext context,
final news.Article article, final news.Article article,
@ -116,13 +111,12 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
: Theme.of(context).textTheme.titleMedium!.copyWith(color: Theme.of(context).disabledColor), : Theme.of(context).textTheme.titleMedium!.copyWith(color: Theme.of(context).disabledColor),
), ),
), ),
if (article.mediaThumbnail != null) ...[ if (article.mediaThumbnail != null)
NeonUrlImage( NeonUrlImage(
url: article.mediaThumbnail!, url: article.mediaThumbnail!,
size: const Size(100, 50), size: const Size(100, 50),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
],
], ],
), ),
subtitle: Row( subtitle: Row(

236
packages/neon/neon_news/lib/widgets/feeds_view.dart

@ -42,128 +42,132 @@ class NewsFeedsView extends StatelessWidget {
final BuildContext context, final BuildContext context,
final news.Feed feed, final news.Feed feed,
final List<news.Folder> folders, final List<news.Folder> folders,
) => ) {
ListTile( Widget trailing = PopupMenuButton<NewsFeedAction>(
title: Text( itemBuilder: (final context) => [
feed.title, PopupMenuItem(
style: feed.unreadCount! == 0 value: NewsFeedAction.showURL,
? Theme.of(context).textTheme.titleMedium!.copyWith(color: Theme.of(context).disabledColor) child: Text(NewsLocalizations.of(context).feedShowURL),
: null,
), ),
subtitle: feed.unreadCount! > 0 PopupMenuItem(
? Text(NewsLocalizations.of(context).articlesUnread(feed.unreadCount!)) value: NewsFeedAction.delete,
: const SizedBox(), child: Text(NewsLocalizations.of(context).actionDelete),
leading: NewsFeedIcon(feed: feed),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (feed.updateErrorCount > 0) ...[
IconButton(
onPressed: () async {
await showDialog<void>(
context: context,
builder: (final context) => NewsFeedUpdateErrorDialog(
feed: feed,
),
);
},
tooltip: NewsLocalizations.of(context).feedShowErrorMessage,
iconSize: 30,
icon: Text(
feed.updateErrorCount.toString(),
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
),
],
PopupMenuButton<NewsFeedAction>(
itemBuilder: (final context) => [
PopupMenuItem(
value: NewsFeedAction.showURL,
child: Text(NewsLocalizations.of(context).feedShowURL),
),
PopupMenuItem(
value: NewsFeedAction.delete,
child: Text(NewsLocalizations.of(context).actionDelete),
),
PopupMenuItem(
value: NewsFeedAction.rename,
child: Text(NewsLocalizations.of(context).actionRename),
),
if (folders.isNotEmpty) ...[
PopupMenuItem(
value: NewsFeedAction.move,
child: Text(NewsLocalizations.of(context).actionMove),
),
],
],
onSelected: (final action) async {
switch (action) {
case NewsFeedAction.showURL:
await showDialog<void>(
context: context,
builder: (final context) => NewsFeedShowURLDialog(
feed: feed,
),
);
case NewsFeedAction.delete:
if (!context.mounted) {
return;
}
if (await showConfirmationDialog(
context,
NewsLocalizations.of(context).feedRemoveConfirm(feed.title),
)) {
bloc.removeFeed(feed.id);
}
case NewsFeedAction.rename:
if (!context.mounted) {
return;
}
final result = await showRenameDialog(
context: context,
title: NewsLocalizations.of(context).feedRename,
value: feed.title,
);
if (result != null) {
bloc.renameFeed(feed.id, result);
}
case NewsFeedAction.move:
if (!context.mounted) {
return;
}
final result = await showDialog<List<int?>>(
context: context,
builder: (final context) => NewsMoveFeedDialog(
folders: folders,
feed: feed,
),
);
if (result != null) {
bloc.moveFeed(feed.id, result[0]);
}
}
},
),
],
), ),
onLongPress: () { PopupMenuItem(
if (feed.unreadCount! > 0) { value: NewsFeedAction.rename,
bloc.markFeedAsRead(feed.id); child: Text(NewsLocalizations.of(context).actionRename),
} ),
}, if (folders.isNotEmpty) ...[
onTap: () async { PopupMenuItem(
await Navigator.of(context).push( value: NewsFeedAction.move,
MaterialPageRoute<void>( child: Text(NewsLocalizations.of(context).actionMove),
builder: (final context) => NewsFeedPage( ),
bloc: bloc, ],
],
onSelected: (final action) async {
switch (action) {
case NewsFeedAction.showURL:
await showDialog<void>(
context: context,
builder: (final context) => NewsFeedShowURLDialog(
feed: feed, feed: feed,
), ),
);
case NewsFeedAction.delete:
if (!context.mounted) {
return;
}
if (await showConfirmationDialog(
context,
NewsLocalizations.of(context).feedRemoveConfirm(feed.title),
)) {
bloc.removeFeed(feed.id);
}
case NewsFeedAction.rename:
if (!context.mounted) {
return;
}
final result = await showRenameDialog(
context: context,
title: NewsLocalizations.of(context).feedRename,
value: feed.title,
);
if (result != null) {
bloc.renameFeed(feed.id, result);
}
case NewsFeedAction.move:
if (!context.mounted) {
return;
}
final result = await showDialog<List<int?>>(
context: context,
builder: (final context) => NewsMoveFeedDialog(
folders: folders,
feed: feed,
),
);
if (result != null) {
bloc.moveFeed(feed.id, result[0]);
}
}
},
);
if (feed.updateErrorCount > 0) {
trailing = Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () async {
await showDialog<void>(
context: context,
builder: (final context) => NewsFeedUpdateErrorDialog(
feed: feed,
),
);
},
tooltip: NewsLocalizations.of(context).feedShowErrorMessage,
iconSize: 30,
icon: Text(
feed.updateErrorCount.toString(),
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
), ),
); ),
}, trailing,
],
); );
}
return ListTile(
title: Text(
feed.title,
style: feed.unreadCount! == 0
? Theme.of(context).textTheme.titleMedium!.copyWith(color: Theme.of(context).disabledColor)
: null,
),
subtitle: feed.unreadCount! > 0
? Text(NewsLocalizations.of(context).articlesUnread(feed.unreadCount!))
: const SizedBox(),
leading: NewsFeedIcon(feed: feed),
trailing: trailing,
onLongPress: () {
if (feed.unreadCount! > 0) {
bloc.markFeedAsRead(feed.id);
}
},
onTap: () async {
await Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (final context) => NewsFeedPage(
bloc: bloc,
feed: feed,
),
),
);
},
);
}
} }
enum NewsFeedAction { enum NewsFeedAction {

27
packages/neon/neon_notes/lib/dialogs/create_note.dart

@ -53,28 +53,25 @@ class _NotesCreateNoteDialogState extends State<NotesCreateNoteDialog> {
submit(); submit();
}, },
), ),
if (widget.category == null) ...[ if (widget.category == null && notes.hasError)
Center( Center(
child: NeonError( child: NeonError(
notes.error, notes.error,
onRetry: widget.bloc.refresh, onRetry: widget.bloc.refresh,
), ),
), ),
Center( if (widget.category == null && notes.isLoading)
child: NeonLinearProgressIndicator( const Center(
visible: notes.isLoading, child: NeonLinearProgressIndicator(),
), ),
if (widget.category == null && notes.hasData)
NotesCategorySelect(
categories: notes.requireData.map((final note) => note.category).toSet().toList(),
onChanged: (final category) {
selectedCategory = category;
},
onSubmitted: submit,
), ),
if (notes.hasData) ...[
NotesCategorySelect(
categories: notes.requireData.map((final note) => note.category).toSet().toList(),
onChanged: (final category) {
selectedCategory = category;
},
onSubmitted: submit,
),
],
],
ElevatedButton( ElevatedButton(
onPressed: submit, onPressed: submit,
child: Text(NotesLocalizations.of(context).noteCreate), child: Text(NotesLocalizations.of(context).noteCreate),

Loading…
Cancel
Save