mirror of
https://github.com/foss42/apidash.git
synced 2025-12-01 02:07:00 +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 'home_page/home_page.dart';
|
||||||
import 'history/history_page.dart';
|
import 'history/history_page.dart';
|
||||||
import 'settings_page.dart';
|
import 'settings_page.dart';
|
||||||
|
import 'terminal/terminal_page.dart';
|
||||||
|
|
||||||
class Dashboard extends ConsumerWidget {
|
class Dashboard extends ConsumerWidget {
|
||||||
const Dashboard({super.key});
|
const Dashboard({super.key});
|
||||||
@@ -70,6 +71,19 @@ class Dashboard extends ConsumerWidget {
|
|||||||
'History',
|
'History',
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
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(
|
Expanded(
|
||||||
@@ -121,6 +135,7 @@ class Dashboard extends ConsumerWidget {
|
|||||||
EnvironmentPage(),
|
EnvironmentPage(),
|
||||||
HistoryPage(),
|
HistoryPage(),
|
||||||
SettingsPage(),
|
SettingsPage(),
|
||||||
|
TerminalPage(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'requests_page/requests_page.dart';
|
|||||||
import '../envvar/environment_page.dart';
|
import '../envvar/environment_page.dart';
|
||||||
import '../history/history_page.dart';
|
import '../history/history_page.dart';
|
||||||
import '../settings_page.dart';
|
import '../settings_page.dart';
|
||||||
|
import '../terminal/terminal_page.dart';
|
||||||
import 'widgets/page_base.dart';
|
import 'widgets/page_base.dart';
|
||||||
import 'navbar.dart';
|
import 'navbar.dart';
|
||||||
|
|
||||||
@@ -77,6 +78,8 @@ class PageBranch extends ConsumerWidget {
|
|||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
scaffoldBody: SettingsPage(),
|
scaffoldBody: SettingsPage(),
|
||||||
);
|
);
|
||||||
|
case 4:
|
||||||
|
return const TerminalPage();
|
||||||
default:
|
default:
|
||||||
return const RequestResponsePage();
|
return const RequestResponsePage();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ class BottomNavBar extends ConsumerWidget {
|
|||||||
label: 'History',
|
label: 'History',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
child: NavbarButton(
|
||||||
|
railIdx: railIdx,
|
||||||
|
buttonIdx: 4,
|
||||||
|
selectedIcon: Icons.terminal,
|
||||||
|
icon: Icons.terminal,
|
||||||
|
label: 'Terminal',
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NavbarButton(
|
child: NavbarButton(
|
||||||
railIdx: railIdx,
|
railIdx: railIdx,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export 'dashboard.dart';
|
export 'dashboard.dart';
|
||||||
export 'mobile/mobile.dart';
|
export 'mobile/mobile.dart';
|
||||||
export 'home_page/collection_pane.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