Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/core/theme/theme_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,13 @@ class ThemeController extends ChangeNotifier with WidgetsBindingObserver {

Future<void> setThemeMode(ThemeMode mode) async {
_themeMode = mode;
final effectiveBrightness = _effectiveBrightness();
if (_registryTheme != null &&
_registryTheme!.brightness != effectiveBrightness) {
await _clearRegistrySelection();
}
if (_registryTheme == null && _preset != QueryaThemePreset.imported) {
_preset = mode == ThemeMode.light
_preset = effectiveBrightness == Brightness.light
? QueryaThemePreset.queryaLight
: QueryaThemePreset.queryaDark;
await AppSettings.instance.setThemePreset(_preset);
Expand Down
33 changes: 30 additions & 3 deletions lib/features/workspace/generic_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import 'package:querya_desktop/features/workspace/sql_query_tab_session.dart';
import 'package:querya_desktop/features/workspace/sql_result_grid_schema.dart';
import 'package:querya_desktop/features/workspace/table_view_staging.dart';
import 'package:querya_desktop/features/workspace/sql_workspace_toolbar.dart';
import 'package:querya_desktop/core/theme/querya_theme.dart';
import 'package:querya_desktop/core/theme/querya_theme_scope.dart';
import 'package:querya_desktop/shared/widgets/widgets.dart';

/// Reusable base SQL workspace supporting multi-tab editing, statement execution,
Expand Down Expand Up @@ -169,6 +171,18 @@ class GenericSqlWorkspaceState extends material.State<GenericSqlWorkspace> {
}
}

QueryaTheme? _lastTheme;

@override
void didChangeDependencies() {
super.didChangeDependencies();
final theme = QueryaThemeScope.maybeOf(context);
if (_lastTheme != null && _lastTheme != theme) {
invalidateAllPanes();
}
_lastTheme = theme;
}

SqlExecutionDelegate? _catalogDelegate;

SqlExecutionDelegate get _diagramDelegate {
Expand Down Expand Up @@ -1269,9 +1283,7 @@ class GenericSqlWorkspaceState extends material.State<GenericSqlWorkspace> {
top: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
material.Container(
padding: const material.EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: SqlEditorChrome.sqlToolbarDecoration(context),
_SqlWorkspaceToolbarContainer(
child: SqlWorkspaceToolbar(
session: session,
delegate: widget.delegate,
Expand Down Expand Up @@ -1356,3 +1368,18 @@ class GenericSqlWorkspaceState extends material.State<GenericSqlWorkspace> {
);
}
}

class _SqlWorkspaceToolbarContainer extends StatelessWidget {
const _SqlWorkspaceToolbarContainer({required this.child});

final material.Widget child;

@override
material.Widget build(material.BuildContext context) {
return material.Container(
padding: const material.EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: SqlEditorChrome.sqlToolbarDecoration(context),
child: child,
);
}
}
2 changes: 1 addition & 1 deletion lib/features/workspace/sql_editor_chrome.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SqlEditorChrome extends StatelessWidget {
) {
final workbench = context.workbench;
return material.BoxDecoration(
color: workbench.surface.withValues(alpha: 0.85),
color: workbench.surface,
border: material.Border(
bottom: material.BorderSide(
color: workbench.borderSubtle.withValues(alpha: 0.35),
Expand Down
21 changes: 21 additions & 0 deletions test/core/theme/theme_controller_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,27 @@ void main() {
expect(await AppSettings.instance.getSelectedThemeId(), isNull);
});

test(
'setThemeMode clears conflicting registry selection and aligns preset (#1577)',
() async {
final c = ThemeController.instance;
await _copyFixture(
'querya_custom_dark.json',
File(p.join(themesDir.path, 'querya_custom_dark.json')),
);
await c.load();
await c.setThemeById('fixture-custom-dark');
expect(c.selectedThemeId, 'fixture-custom-dark');
expect(c.activeTheme.brightness, Brightness.dark);

await c.setThemeMode(ThemeMode.light);

expect(c.selectedThemeId, isNull);
expect(c.activeTheme, QueryaTheme.lightDefault);
expect(c.preset, QueryaThemePreset.queryaLight);
expect(await AppSettings.instance.getSelectedThemeId(), isNull);
});

test('setThemeById applies built-in asset theme from registry', () async {
final c = ThemeController.instance;
await c.load();
Expand Down
56 changes: 56 additions & 0 deletions test/features/workspace/generic_sql_workspace_sessions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:querya_desktop/core/actions/sql_editor_command_bridge.dart';
import 'package:querya_desktop/core/database/table_mutation_engine.dart';
import 'package:querya_desktop/core/storage/local_db.dart';
import 'package:querya_desktop/core/theme/querya_theme.dart';
import 'package:querya_desktop/features/workspace/generic_sql_workspace.dart';
import 'package:querya_desktop/features/workspace/sql_workspace_toolbar.dart';

import '../../support/fake_sql_execution_delegate.dart';
import '../../support/local_db_test_support.dart';
Expand Down Expand Up @@ -254,4 +256,58 @@ void main() {
() => Future<void>.delayed(const Duration(milliseconds: 100)),
);
});

testWidgets(
'updates toolbar background when theme switches between dark and light (#1577)',
timeout: _timeout, (tester) async {
final delegate = FakeSqlExecutionDelegate();
await tester.binding.setSurfaceSize(const material.Size(1200, 800));
addTearDown(() => tester.binding.setSurfaceSize(null));

material.Widget buildWithTheme(QueryaTheme theme) {
return queryaThemeTestShell(
data: theme,
child: material.SizedBox.expand(
child: GenericSqlWorkspace(
connectionRow: connection,
delegate: delegate,
dialect: SqlDialect.sqlite,
),
),
);
}

// 1. Initial dark theme mount
await tester.pumpWidget(buildWithTheme(QueryaTheme.darkDefault));
await tester.pumpAndSettle();

final toolbarFinder = find.byType(SqlWorkspaceToolbar);
expect(toolbarFinder, findsOneWidget);

material.BoxDecoration getToolbarDecoration() {
final container = tester.widget<material.Container>(
find
.ancestor(
of: toolbarFinder,
matching: find.byType(material.Container),
)
.first,
);
return container.decoration! as material.BoxDecoration;
}

expect(
getToolbarDecoration().color,
QueryaTheme.darkDefault.workbench.surface,
);

// 2. Switch to light theme
await tester.pumpWidget(buildWithTheme(QueryaTheme.lightDefault));
await tester.pumpAndSettle();

expect(
getToolbarDecoration().color,
QueryaTheme.lightDefault.workbench.surface,
);
});
}
48 changes: 48 additions & 0 deletions test/features/workspace/sql_editor_chrome_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,52 @@ void main() {
expect(outerGlow, const Color(0xFF00FFEE).withValues(alpha: 0.1));
});
});

group('SqlEditorChrome.sqlToolbarDecoration', () {
testWidgets('uses solid surface and subtle border in dark theme',
(tester) async {
late material.BoxDecoration deco;
await tester.pumpWidget(
queryaThemeTestShell(
data: QueryaTheme.darkDefault,
child: material.Builder(
builder: (context) {
deco = SqlEditorChrome.sqlToolbarDecoration(context);
return const material.SizedBox.shrink();
},
),
),
);
expect(deco.color, QueryaTheme.darkDefault.workbench.surface);
final border = deco.border as Border?;
expect(
border?.bottom.color,
QueryaTheme.darkDefault.workbench.borderSubtle
.withValues(alpha: 0.35),
);
});

testWidgets('uses solid surface and subtle border in light theme',
(tester) async {
late material.BoxDecoration deco;
await tester.pumpWidget(
queryaThemeTestShell(
data: QueryaTheme.lightDefault,
child: material.Builder(
builder: (context) {
deco = SqlEditorChrome.sqlToolbarDecoration(context);
return const material.SizedBox.shrink();
},
),
),
);
expect(deco.color, QueryaTheme.lightDefault.workbench.surface);
final border = deco.border as Border?;
expect(
border?.bottom.color,
QueryaTheme.lightDefault.workbench.borderSubtle
.withValues(alpha: 0.35),
);
});
});
}
Loading