diff --git a/lib/features/connections/driver_icon.dart b/lib/features/connections/driver_icon.dart index 7b51daed..c75480d1 100644 --- a/lib/features/connections/driver_icon.dart +++ b/lib/features/connections/driver_icon.dart @@ -5,6 +5,14 @@ import 'package:flutter/material.dart' as material; import 'package:flutter_svg/flutter_svg.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +/// Brightens every channel (x1.9 and a small lift), alpha untouched. +const _liftDarkIcon = material.ColorFilter.matrix([ + 1.9, 0, 0, 0, 40, // + 0, 1.9, 0, 0, 40, + 0, 0, 1.9, 0, 40, + 0, 0, 0, 1, 0, +]); + /// Renders a bundled or extension-provided database icon with one fallback. class DriverIcon extends StatelessWidget { const DriverIcon({ @@ -37,7 +45,7 @@ class DriverIcon extends StatelessWidget { } if (assetPath != null) { final cacheSize = (size * MediaQuery.devicePixelRatioOf(context)).toInt(); - return material.Image.asset( + final image = material.Image.asset( assetPath!, width: size, height: size, @@ -47,6 +55,16 @@ class DriverIcon extends StatelessWidget { filterQuality: material.FilterQuality.medium, errorBuilder: (_, __, ___) => fallback, ); + // The MySQL dolphin is dark blue and nearly vanishes on a dark surface + // (#1824): lift it there, leave the light theme alone. + if (assetPath!.endsWith('mysql_icon.png') && + material.Theme.of(context).brightness == material.Brightness.dark) { + return material.ColorFiltered( + colorFilter: _liftDarkIcon, + child: image, + ); + } + return image; } return fallback; } diff --git a/lib/features/mongodb/mongo_collections_view.dart b/lib/features/mongodb/mongo_collections_view.dart index 725519cd..ac3b75d4 100644 --- a/lib/features/mongodb/mongo_collections_view.dart +++ b/lib/features/mongodb/mongo_collections_view.dart @@ -86,7 +86,11 @@ class _MongoCollectionsViewState extends material.State { _statsTotal = 0; }); try { - final names = await widget.connection.listCollections(widget.database); + // The sidebar tree lists them sorted by name; the same order here + // (#1824) instead of the server's. + final names = [ + ...await widget.connection.listCollections(widget.database), + ]..sort(); if (!mounted || gen != _loadGeneration) return; setState(() { diff --git a/test/features/connections/driver_icon_test.dart b/test/features/connections/driver_icon_test.dart index 69e26b2c..37d6bca9 100644 --- a/test/features/connections/driver_icon_test.dart +++ b/test/features/connections/driver_icon_test.dart @@ -34,4 +34,35 @@ void main() { expect(find.byIcon(material.Icons.extension_rounded), findsOneWidget); }); + + Future pumpIcon(WidgetTester tester, String asset, + {bool light = false}) async { + await tester.pumpWidget( + queryaThemeTestShell( + theme: light ? material.ThemeData.light() : null, + child: DriverIcon( + assetPath: asset, + size: 32, + fallbackIcon: material.Icons.storage_rounded, + ), + ), + ); + } + + group('MySQL logo on a dark surface (#1824)', () { + testWidgets('is lifted on the dark theme', (tester) async { + await pumpIcon(tester, 'assets/images/mysql_icon.png'); + expect(find.byType(material.ColorFiltered), findsOneWidget); + }); + + testWidgets('is left alone on the light theme', (tester) async { + await pumpIcon(tester, 'assets/images/mysql_icon.png', light: true); + expect(find.byType(material.ColorFiltered), findsNothing); + }); + + testWidgets('other logos are never filtered', (tester) async { + await pumpIcon(tester, 'assets/images/postgresql_icon.png'); + expect(find.byType(material.ColorFiltered), findsNothing); + }); + }); }