feat: add terminal page ui

This commit is contained in:
Udhay-Adithya
2025-09-07 23:49:57 +05:30
parent 121aac80c9
commit e29448ed46
5 changed files with 103 additions and 0 deletions

View File

@@ -10,6 +10,7 @@ import 'envvar/environment_page.dart';
import 'home_page/home_page.dart';
import 'history/history_page.dart';
import 'settings_page.dart';
import 'terminal/terminal_page.dart';
class Dashboard extends ConsumerWidget {
const Dashboard({super.key});
@@ -70,6 +71,19 @@ class Dashboard extends ConsumerWidget {
'History',
style: Theme.of(context).textTheme.labelSmall,
),
kVSpacer10,
IconButton(
isSelected: railIdx == 4,
onPressed: () {
ref.read(navRailIndexStateProvider.notifier).state = 4;
},
icon: const Icon(Icons.terminal),
selectedIcon: const Icon(Icons.terminal),
),
Text(
'Terminal',
style: Theme.of(context).textTheme.labelSmall,
),
],
),
Expanded(
@@ -121,6 +135,7 @@ class Dashboard extends ConsumerWidget {
EnvironmentPage(),
HistoryPage(),
SettingsPage(),
TerminalPage(),
],
),
)

View File

@@ -8,6 +8,7 @@ import 'requests_page/requests_page.dart';
import '../envvar/environment_page.dart';
import '../history/history_page.dart';
import '../settings_page.dart';
import '../terminal/terminal_page.dart';
import 'widgets/page_base.dart';
import 'navbar.dart';
@@ -77,6 +78,8 @@ class PageBranch extends ConsumerWidget {
title: 'Settings',
scaffoldBody: SettingsPage(),
);
case 4:
return const TerminalPage();
default:
return const RequestResponsePage();
}

View File

@@ -57,6 +57,15 @@ class BottomNavBar extends ConsumerWidget {
label: 'History',
),
),
Expanded(
child: NavbarButton(
railIdx: railIdx,
buttonIdx: 4,
selectedIcon: Icons.terminal,
icon: Icons.terminal,
label: 'Terminal',
),
),
Expanded(
child: NavbarButton(
railIdx: railIdx,

View File

@@ -1,3 +1,4 @@
export 'dashboard.dart';
export 'mobile/mobile.dart';
export 'home_page/collection_pane.dart';
export 'terminal/terminal_page.dart';

View File

@@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/terminal_models.dart';
import '../../providers/terminal_providers.dart';
class TerminalPage extends ConsumerWidget {
const TerminalPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(terminalStateProvider);
final entries = state.entries;
return Scaffold(
appBar: AppBar(title: const Text('Terminal')),
body: ListView.separated(
itemCount: entries.length,
separatorBuilder: (_, __) => const Divider(height: 1),
itemBuilder: (ctx, i) {
final e = entries[i];
final title = _titleFor(e);
final subtitle = _subtitleFor(e);
final icon = _iconFor(e);
return ListTile(
leading: Icon(icon),
title: Text(title, maxLines: 1, overflow: TextOverflow.ellipsis),
subtitle: Text(subtitle ?? '',
maxLines: 2, overflow: TextOverflow.ellipsis),
dense: true,
);
},
),
);
}
IconData _iconFor(TerminalEntry e) {
switch (e.source) {
case TerminalSource.network:
return Icons.language;
case TerminalSource.js:
return Icons.javascript;
case TerminalSource.system:
return Icons.info_outline;
}
}
String _titleFor(TerminalEntry e) {
switch (e.source) {
case TerminalSource.network:
final n = e.network!;
final status = n.responseStatus != null ? '${n.responseStatus}' : '';
return '${n.method.name.toUpperCase()} ${n.url}$status';
case TerminalSource.js:
final j = e.js!;
return 'JS ${j.level}';
case TerminalSource.system:
return 'System';
}
}
String? _subtitleFor(TerminalEntry e) {
switch (e.source) {
case TerminalSource.network:
final n = e.network!;
if (n.errorMessage != null) return n.errorMessage;
return n.responseBodyPreview ?? n.requestBodyPreview;
case TerminalSource.js:
final j = e.js!;
return j.args.join(' ');
case TerminalSource.system:
final s = e.system!;
return s.message;
}
}
}