mirror of
https://github.com/foss42/apidash.git
synced 2025-11-30 17:59:18 +08:00
feat: add terminal page ui
This commit is contained in:
@@ -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(),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export 'dashboard.dart';
|
||||
export 'mobile/mobile.dart';
|
||||
export 'home_page/collection_pane.dart';
|
||||
export 'terminal/terminal_page.dart';
|
||||
|
||||
75
lib/screens/terminal/terminal_page.dart
Normal file
75
lib/screens/terminal/terminal_page.dart
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user