Browse Source

Merge pull request #734 from nextcloud/refactor/icon-sizes

refactor(neon): Refactor icon sizes
pull/743/head
Kate 1 year ago committed by GitHub
parent
commit
4ba933d42f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      packages/neon/neon/lib/src/models/app_implementation.dart
  2. 3
      packages/neon/neon/lib/src/pages/home.dart
  3. 5
      packages/neon/neon/lib/src/theme/sizes.dart
  4. 4
      packages/neon/neon/lib/src/widgets/app_bar.dart
  5. 5
      packages/neon/neon/lib/src/widgets/app_implementation_icon.dart
  6. 10
      packages/neon/neon/lib/src/widgets/drawer_destination.dart
  7. 10
      packages/neon/neon/lib/src/widgets/unified_search_results.dart
  8. 9
      packages/neon/neon/lib/src/widgets/user_avatar.dart
  9. 1
      packages/neon/neon/lib/theme.dart
  10. 1
      packages/neon/neon_files/lib/neon_files.dart
  11. 6
      packages/neon/neon_files/lib/widgets/browser_view.dart
  12. 7
      packages/neon/neon_files/lib/widgets/file_list_tile.dart
  13. 2
      packages/neon/neon_files/lib/widgets/file_preview.dart
  14. 1
      packages/neon/neon_news/lib/neon_news.dart
  15. 2
      packages/neon/neon_news/lib/widgets/articles_view.dart
  16. 2
      packages/neon/neon_news/lib/widgets/feed_icon.dart
  17. 4
      packages/neon/neon_news/lib/widgets/folders_view.dart
  18. 1
      packages/neon/neon_notes/lib/neon_notes.dart
  19. 4
      packages/neon/neon_notes/lib/widgets/categories_view.dart
  20. 2
      packages/neon/neon_notes/lib/widgets/notes_view.dart
  21. 1
      packages/neon/neon_notifications/lib/neon_notifications.dart
  22. 6
      packages/neon/neon_notifications/lib/pages/main.dart

13
packages/neon/neon/lib/src/models/app_implementation.dart

@ -91,20 +91,23 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
}
Widget buildIcon({
final Size size = const Size.square(32),
final double? size,
final Color? color,
}) =>
Builder(
builder: (final context) => VectorGraphic(
width: size.width,
height: size.height,
builder: (final context) {
final realSize = size ?? IconTheme.of(context).size;
return VectorGraphic(
width: realSize,
height: realSize,
colorFilter: ColorFilter.mode(color ?? Theme.of(context).colorScheme.primary, BlendMode.srcIn),
loader: AssetBytesLoader(
'assets/app.svg.vec',
packageName: 'neon_$id',
),
semanticsLabel: AppLocalizations.of(context).nextcloudLogo,
),
);
},
);
@mustCallSuper

3
packages/neon/neon/lib/src/pages/home.dart

@ -14,11 +14,8 @@ import 'package:neon/src/widgets/app_bar.dart';
import 'package:neon/src/widgets/drawer.dart';
import 'package:neon/src/widgets/exception.dart';
import 'package:neon/src/widgets/unified_search_results.dart';
import 'package:neon/src/widgets/user_avatar.dart';
import 'package:provider/provider.dart';
const kQuickBarWidth = kAvatarSize + 20;
class HomePage extends StatefulWidget {
const HomePage({
super.key,

5
packages/neon/neon/lib/src/theme/sizes.dart

@ -0,0 +1,5 @@
/// Used for large icons e.g. in the leading part of a ListTile.
const largeIconSize = 40.0;
/// Use for small icons e.g. in the subtitle part of a ListTile.
const smallIconSize = 16.0;

4
packages/neon/neon/lib/src/widgets/app_bar.dart

@ -13,7 +13,6 @@ import 'package:neon/src/widgets/account_switcher_button.dart';
import 'package:neon/src/widgets/app_implementation_icon.dart';
import 'package:neon/src/widgets/exception.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:neon/src/widgets/user_avatar.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
@ -131,7 +130,6 @@ class _NeonAppBarState extends State<NeonAppBar> {
tooltip: AppLocalizations.of(context).searchCancel,
icon: const Icon(
Icons.close,
size: kAvatarSize * 2 / 3,
),
),
],
@ -164,7 +162,6 @@ class SearchIconButton extends StatelessWidget {
tooltip: AppLocalizations.of(context).search,
icon: const Icon(
Icons.search,
size: kAvatarSize * 2 / 3,
),
);
}
@ -269,7 +266,6 @@ class _NotificationIconButtonState extends State<NotificationIconButton> {
color: unreadCount > 0
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onBackground,
size: const Size.square(kAvatarSize * 2 / 3),
),
);
},

5
packages/neon/neon/lib/src/widgets/app_implementation_icon.dart

@ -1,7 +1,6 @@
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/widgets/user_avatar.dart';
@internal
class NeonAppImplementationIcon extends StatelessWidget {
@ -9,7 +8,7 @@ class NeonAppImplementationIcon extends StatelessWidget {
required this.appImplementation,
this.unreadCount = 0,
this.color,
this.size = const Size.square(kAvatarSize),
this.size,
super.key,
});
@ -19,7 +18,7 @@ class NeonAppImplementationIcon extends StatelessWidget {
final Color? color;
final Size size;
final double? size;
@override
Widget build(final BuildContext context) => Stack(

10
packages/neon/neon/lib/src/widgets/drawer_destination.dart

@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:neon/src/widgets/user_avatar.dart';
import 'package:rxdart/subjects.dart';
@internal
typedef DestinationIconBuilder = Widget Function({Size size, Color color});
typedef DestinationIconBuilder = Widget Function({double? size, Color color});
@internal
class NeonNavigationDestination {
@ -34,18 +33,17 @@ extension NavigationDestinationExtension on NavigationDestination {
@internal
extension NavigationRailDestinationExtension on NavigationRailDestination {
static NavigationRailDestination fromNeonDestination(final NeonNavigationDestination neonDestination) {
final iconWIdget = StreamBuilder(
final iconWidget = StreamBuilder(
stream: neonDestination.notificationCount,
initialData: 0,
builder: (final context, final snapshot) {
final colorScheme = Theme.of(context).colorScheme;
final color = snapshot.requireData > 0 ? colorScheme.primary : colorScheme.onBackground;
const size = Size.square(kAvatarSize * 2 / 3);
final icon = Container(
margin: const EdgeInsets.all(5),
child: neonDestination.icon(size: size, color: color),
child: neonDestination.icon(color: color),
);
if (snapshot.requireData <= 0) {
@ -78,7 +76,7 @@ extension NavigationRailDestinationExtension on NavigationRailDestination {
return NavigationRailDestination(
label: Text(neonDestination.label),
icon: iconWIdget,
icon: iconWidget,
selectedIcon: neonDestination.selectedIcon,
);
}

10
packages/neon/neon/lib/src/widgets/unified_search_results.dart

@ -7,13 +7,13 @@ import 'package:neon/src/bloc/result_builder.dart';
import 'package:neon/src/blocs/accounts.dart';
import 'package:neon/src/blocs/unified_search.dart';
import 'package:neon/src/models/account.dart';
import 'package:neon/src/theme/sizes.dart';
import 'package:neon/src/widgets/cached_image.dart';
import 'package:neon/src/widgets/exception.dart';
import 'package:neon/src/widgets/image_wrapper.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart';
import 'package:neon/src/widgets/list_view.dart';
import 'package:neon/src/widgets/server_icon.dart';
import 'package:neon/src/widgets/user_avatar.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:provider/provider.dart';
@ -77,7 +77,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
ListTile(
leading: const Icon(
Icons.close,
size: kAvatarSize,
size: largeIconSize,
),
title: Text(AppLocalizations.of(context).searchNoResults),
),
@ -85,7 +85,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
for (final entry in entries) ...[
ListTile(
leading: NeonImageWrapper(
size: const Size.square(kAvatarSize),
size: const Size.square(largeIconSize),
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: _buildThumbnail(context, accountsBloc.activeAccount.value!, entry),
),
@ -105,7 +105,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
Widget _buildThumbnail(final BuildContext context, final Account account, final CoreUnifiedSearchResultEntry entry) {
if (entry.thumbnailUrl.isNotEmpty) {
return NeonCachedImage.url(
size: const Size.square(kAvatarSize),
size: const Size.square(largeIconSize),
url: entry.thumbnailUrl,
account: account,
// The thumbnail URL might be set but a 404 is returned because there is no preview available
@ -121,7 +121,7 @@ class NeonUnifiedSearchResults extends StatelessWidget {
final Account account,
final CoreUnifiedSearchResultEntry entry,
) {
const size = Size.square(kAvatarSize * 2 / 3);
final size = Size.square(IconTheme.of(context).size!);
if (entry.icon.startsWith('/')) {
return NeonCachedImage.url(
size: size,

9
packages/neon/neon/lib/src/widgets/user_avatar.dart

@ -8,20 +8,19 @@ import 'package:neon/src/bloc/result.dart';
import 'package:neon/src/bloc/result_builder.dart';
import 'package:neon/src/blocs/accounts.dart';
import 'package:neon/src/models/account.dart';
import 'package:neon/src/theme/sizes.dart';
import 'package:neon/src/widgets/cached_image.dart';
import 'package:neon/src/widgets/server_icon.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
const kAvatarSize = 40.0;
class NeonUserAvatar extends StatefulWidget {
NeonUserAvatar({
required this.account,
final String? username,
this.showStatus = true,
this.size = kAvatarSize,
this.size,
this.backgroundColor,
this.foregroundColor,
super.key,
@ -30,7 +29,7 @@ class NeonUserAvatar extends StatefulWidget {
final Account account;
final String username;
final bool showStatus;
final double size;
final double? size;
final Color? backgroundColor;
final Color? foregroundColor;
@ -55,7 +54,7 @@ class _UserAvatarState extends State<NeonUserAvatar> {
Widget build(final BuildContext context) => LayoutBuilder(
builder: (final context, final constraints) {
final brightness = Theme.of(context).brightness;
size = constraints.constrain(Size.square(widget.size)).shortestSide;
size = constraints.constrain(Size.square(widget.size ?? largeIconSize)).shortestSide;
final pixelSize = (size * MediaQuery.of(context).devicePixelRatio).toInt();
return Stack(
alignment: Alignment.center,

1
packages/neon/neon/lib/theme.dart

@ -3,3 +3,4 @@ export 'src/theme/color_scheme.dart';
export 'src/theme/colors.dart';
export 'src/theme/dialog.dart';
export 'src/theme/neon.dart';
export 'src/theme/sizes.dart';

1
packages/neon/neon_files/lib/neon_files.dart

@ -18,6 +18,7 @@ import 'package:neon/nextcloud.dart';
import 'package:neon/platform.dart';
import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart';
import 'package:neon/theme.dart';
import 'package:neon/utils.dart';
import 'package:neon/widgets.dart';
import 'package:neon_files/l10n/localizations.dart';

6
packages/neon/neon_files/lib/widgets/browser_view.dart

@ -130,14 +130,9 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
children: <Widget>[
IconButton(
padding: EdgeInsets.zero,
visualDensity: const VisualDensity(
horizontal: VisualDensity.minimumDensity,
vertical: VisualDensity.minimumDensity,
),
tooltip: AppLocalizations.of(context).goToPath(''),
icon: const Icon(
Icons.house,
size: 30,
),
onPressed: () {
widget.bloc.setPath([]);
@ -167,7 +162,6 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
.intersperse(
const Icon(
Icons.keyboard_arrow_right,
size: 30,
),
)
.toList(),

7
packages/neon/neon_files/lib/widgets/file_list_tile.dart

@ -1,6 +1,7 @@
import 'package:filesize/filesize.dart';
import 'package:flutter/material.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:neon/theme.dart';
import 'package:neon/utils.dart';
import 'package:neon/widgets.dart';
import 'package:neon_files/l10n/localizations.dart';
@ -75,7 +76,7 @@ class FileListTile extends StatelessWidget {
trailing: !details.hasTask && mode != FilesBrowserMode.noActions
? FileActions(details: details)
: const SizedBox.square(
dimension: 48,
dimension: largeIconSize,
),
);
}
@ -126,7 +127,7 @@ class _FileIcon extends StatelessWidget {
alignment: Alignment.bottomRight,
child: Icon(
Icons.star,
size: 14,
size: smallIconSize,
color: Colors.yellow,
),
),
@ -135,7 +136,7 @@ class _FileIcon extends StatelessWidget {
}
return SizedBox.square(
dimension: 40,
dimension: largeIconSize,
child: icon,
);
}

2
packages/neon/neon_files/lib/widgets/file_preview.dart

@ -4,7 +4,7 @@ class FilePreview extends StatelessWidget {
const FilePreview({
required this.bloc,
required this.details,
this.size = const Size.square(40),
this.size = const Size.square(largeIconSize),
this.color,
this.borderRadius,
this.withBackground = false,

1
packages/neon/neon_news/lib/neon_news.dart

@ -15,6 +15,7 @@ import 'package:neon/nextcloud.dart';
import 'package:neon/platform.dart';
import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart';
import 'package:neon/theme.dart';
import 'package:neon/utils.dart';
import 'package:neon/widgets.dart';
import 'package:neon_news/l10n/localizations.dart';

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

@ -131,7 +131,7 @@ class _NewsArticlesViewState extends State<NewsArticlesView> {
),
child: NewsFeedIcon(
feed: feed,
size: 16,
size: smallIconSize,
borderRadius: const BorderRadius.all(Radius.circular(2)),
),
),

2
packages/neon/neon_news/lib/widgets/feed_icon.dart

@ -3,7 +3,7 @@ part of '../neon_news.dart';
class NewsFeedIcon extends StatelessWidget {
const NewsFeedIcon({
required this.feed,
this.size = 48,
this.size = largeIconSize,
this.borderRadius,
super.key,
});

4
packages/neon/neon_news/lib/widgets/folders_view.dart

@ -53,12 +53,12 @@ class NewsFoldersView extends StatelessWidget {
),
subtitle: unreadCount > 0 ? Text(AppLocalizations.of(context).articlesUnread(unreadCount)) : const SizedBox(),
leading: SizedBox.square(
dimension: 48,
dimension: largeIconSize,
child: Stack(
children: [
Icon(
Icons.folder,
size: 48,
size: largeIconSize,
color: Theme.of(context).colorScheme.primary,
),
Center(

1
packages/neon/neon_notes/lib/neon_notes.dart

@ -14,6 +14,7 @@ import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/settings.dart';
import 'package:neon/sort_box.dart';
import 'package:neon/theme.dart';
import 'package:neon/utils.dart';
import 'package:neon/widgets.dart';
import 'package:neon_notes/l10n/localizations.dart';

4
packages/neon/neon_notes/lib/widgets/categories_view.dart

@ -46,10 +46,10 @@ class NotesCategoriesView extends StatelessWidget {
leading: category.name.isNotEmpty
? Icon(
MdiIcons.tag,
size: 40,
size: largeIconSize,
color: NotesCategoryColor.compute(category.name),
)
: const SizedBox.square(dimension: 40),
: const SizedBox.square(dimension: largeIconSize),
onTap: () async {
await Navigator.of(context).push(
MaterialPageRoute(

2
packages/neon/neon_notes/lib/widgets/notes_view.dart

@ -50,7 +50,7 @@ class NotesView extends StatelessWidget {
),
Icon(
MdiIcons.tag,
size: 14,
size: smallIconSize,
color: NotesCategoryColor.compute(note.category),
),
const SizedBox(

1
packages/neon/neon_notifications/lib/neon_notifications.dart

@ -9,6 +9,7 @@ import 'package:neon/blocs.dart';
import 'package:neon/models.dart';
import 'package:neon/nextcloud.dart';
import 'package:neon/settings.dart';
import 'package:neon/theme.dart';
import 'package:neon/utils.dart';
import 'package:neon/widgets.dart';
import 'package:neon_notifications/l10n/localizations.dart';

6
packages/neon/neon_notifications/lib/pages/main.dart

@ -74,13 +74,13 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
),
leading: app != null
? app.buildIcon(
size: const Size.square(40),
size: largeIconSize,
)
: SizedBox.fromSize(
size: const Size.square(40),
size: const Size.square(largeIconSize),
child: NeonCachedImage.url(
url: notification.icon!,
size: const Size.square(40),
size: const Size.square(largeIconSize),
svgColor: Theme.of(context).colorScheme.primary,
),
),

Loading…
Cancel
Save