refactor: extract consistent AppBar builder, remove icon from EVENT LOG title

- Add buildTracPulseAppBar() helper in lib/app_bar.dart
  - Reads backgroundColor/elevation from ThemeData.appBarTheme
  - Consistent back button (#9e9e9e, size 20) via Navigator.pop
  - Monospace title style (14px, weight 700, letter-spacing 2)
  - Optional onTitleTap for tappable titles
- Update all screens to use the new helper, removing redundant overrides
- Remove terminal icon from status_screen title, use plain centered text
- Change appBarTheme centerTitle to false (left-aligned)
- Remove bottom dividers from all screens
This commit is contained in:
fiatcode 2026-05-06 08:01:12 +07:00
parent 2123df11c9
commit 4ce1f51062
No known key found for this signature in database
5 changed files with 66 additions and 86 deletions

55
lib/app_bar.dart Normal file
View file

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
/// Consistent AppBar builder for TracPulse screens.
///
/// Reads base styles (backgroundColor, elevation) from the current
/// [ThemeData.appBarTheme], then applies TracPulse's standard back button
/// and title styling on top.
///
/// Parameters:
/// - [title] App bar title text (left-aligned, monospace, 14px, weight 700, letter-spacing 2)
/// - [actions] optional list of action [IconButton]s placed on the right
/// - [onTitleTap] optional callback when the title is tapped (e.g. Easter egg)
AppBar buildTracPulseAppBar({
required String title,
List<Widget>? actions,
VoidCallback? onTitleTap,
}) {
return AppBar(
// Inherit backgroundColor, elevation from theme (defined once in MaterialApp.appBarTheme)
automaticallyImplyLeading: true,
actions: actions,
title: onTitleTap != null
? GestureDetector(
onTap: onTitleTap,
child: Text(
title,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 2,
color: Color(0xFFe0e0e0),
),
),
)
: Text(
title,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 2,
color: Color(0xFFe0e0e0),
),
),
// Consistent back button: #9e9e9e, size 20 (distinct from title #e0e0e0)
leading: Builder(
builder: (context) => IconButton(
icon: const Icon(Icons.arrow_back, color: Color(0xFF9e9e9e), size: 20),
onPressed: () => Navigator.pop(context),
),
),
leadingWidth: 48,
);
}

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'app_bar.dart';
class InfoScreen extends StatelessWidget {
const InfoScreen({super.key});
@ -7,32 +9,7 @@ class InfoScreen extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0d0d0d),
appBar: AppBar(
backgroundColor: const Color(0xFF161616),
elevation: 0,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Color(0xFF9e9e9e),
size: 20,
),
onPressed: () => Navigator.pop(context),
),
title: const Text(
'HOW IT WORKS',
style: TextStyle(
fontFamily: 'monospace',
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 2,
color: Color(0xFFe0e0e0),
),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1),
child: Container(height: 1, color: const Color(0xFF2a2a2a)),
),
),
appBar: buildTracPulseAppBar(title: 'HOW IT WORKS'),
body: ListView(
padding: const EdgeInsets.all(20),
children: [

View file

@ -38,7 +38,7 @@ class TracPulseApp extends StatelessWidget {
secondary: Color(0xFF00e676),
),
appBarTheme: const AppBarTheme(
centerTitle: true,
centerTitle: false,
backgroundColor: Color(0xFF161616),
foregroundColor: Color(0xFFe0e0e0),
elevation: 0,

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
import 'app_bar.dart';
import 'bridge/location_bridge.dart';
import 'info_screen.dart';
import 'preferences.dart';
@ -131,34 +132,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0d0d0d),
appBar: AppBar(
backgroundColor: const Color(0xFF161616),
elevation: 0,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Color(0xFF9e9e9e),
size: 20,
),
onPressed: () => Navigator.pop(context),
),
title: GestureDetector(
onTap: _handleAppBarTap,
child: const Text(
'SETTINGS',
style: TextStyle(
fontFamily: 'monospace',
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 2,
color: Color(0xFFe0e0e0),
),
),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1),
child: Container(height: 1, color: const Color(0xFF2a2a2a)),
),
appBar: buildTracPulseAppBar(
title: 'SETTINGS',
onTitleTap: _handleAppBarTap,
actions: [
IconButton(
icon: const Icon(

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'app_bar.dart';
import 'bridge/location_bridge.dart';
class StatusScreen extends StatefulWidget {
@ -179,33 +180,8 @@ class _StatusScreenState extends State<StatusScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0d0d0d),
appBar: AppBar(
backgroundColor: const Color(0xFF161616),
elevation: 0,
title: Row(
children: [
const Icon(Icons.terminal, color: Color(0xFF00bcd4), size: 18),
const SizedBox(width: 10),
const Text(
'EVENT LOG',
style: TextStyle(
fontFamily: 'monospace',
fontSize: 14,
fontWeight: FontWeight.w700,
letterSpacing: 2,
color: Color(0xFFe0e0e0),
),
),
],
),
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Color(0xFF9e9e9e),
size: 20,
),
onPressed: () => Navigator.pop(context),
),
appBar: buildTracPulseAppBar(
title: 'EVENT LOG',
actions: [
IconButton(
icon: const Icon(
@ -220,10 +196,6 @@ class _StatusScreenState extends State<StatusScreen> {
onPressed: _loadLogs,
),
],
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1),
child: Container(height: 1, color: const Color(0xFF2a2a2a)),
),
),
body: Column(
children: [