Skip to content

Refactor: Resolve UI architecture tech debt and accessibility bugs #196

Description

@ZhuchkaTriplesix

Description

A review of the UI architecture revealed several code-level bugs and technical debt that should be addressed, particularly before expanding the driver ecosystem (like the upcoming SQLite integration in 0.4.5).

1. Open/Closed Principle Violation in workspace_panel.dart

The WorkspacePanel.build method uses a hardcoded if-else chain to determine what UI to render based on the database type:

if (widget.activeConnection!.type == 'postgresql') { ... }
if (widget.activeConnection!.type == 'mysql') { ... }
if (widget.activeConnection!.type == 'mongodb') { ... }

Problem: Every time a new database driver is added, this file must be modified, causing a bottleneck.
Fix: Refactor to use a registry pattern or polymorphism where the connection driver provides a WidgetBuilder (e.g., driver.buildWorkspace(...)).

2. Accessibility Text Scaling Override in app.dart

The root QueryaApp builder overrides the system text scaling:

textScaler: TextScaler.linear(scale),

Problem: TextScaler.linear replaces the OS-provided text scale. If a visually impaired user has their OS text scale set to 150%, the app forcefully resets it.
Fix: Multiply the internal scale with the system scale:

textScaler: (mq ?? const MediaQueryData()).textScaler.scale(scale),

3. Redundant Null Checks & Dirty Logic in workspace_panel.dart

There is repeated null checking in workspace_panel.dart despite early checks:

if (widget.activeConnection != null && widget.activeConnection!.type == 'postgresql') { ... }

Problem: Since the very first check in the build method is an early return if activeConnection == null, all subsequent != null and ! checks are redundant and add visual noise.
Fix: Extract final conn = widget.activeConnection; at the top, execute the early return, and then safely use conn.type without null-check operators.

4. Heavy Rebuilds on Sub-tree in querya_dropdown.dart

The _QueryaDropdownState triggers setState(() => _menuOpen = true) inside the MenuAnchor.onOpen callback.
Problem: Triggers a rebuild of the entire dropdown widget just to animate the menu.
Fix: Keep the open/closed state localized via an AnimatedBuilder attached to the MenuController's internal state (or a smaller ValueNotifier).

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions