This commit is contained in:
John Smith 2022-12-14 16:50:33 -05:00
parent 78d06fb187
commit f0674e46d1
6 changed files with 235 additions and 60 deletions

View File

@ -101,9 +101,11 @@ impl TableStore {
let db = Database::open(table_name.clone(), column_count) let db = Database::open(table_name.clone(), column_count)
.await .await
.wrap_err("failed to open tabledb")?; .wrap_err("failed to open tabledb")?;
info!( trace!(
"opened table store '{}' with table name '{:?}' with {} columns", "opened table store '{}' with table name '{:?}' with {} columns",
name, table_name, column_count name,
table_name,
column_count
); );
let table_db = TableDB::new(table_name.clone(), self.clone(), db); let table_db = TableDB::new(table_name.clone(), self.clone(), db);

View File

@ -445,6 +445,10 @@ impl VeilidAPI {
Ok("Connections purged".to_owned()) Ok("Connections purged".to_owned())
} else if args[0] == "routes" { } else if args[0] == "routes" {
// Purge route spec store // Purge route spec store
{
let mut dc = DEBUG_CACHE.lock();
dc.imported_routes.clear();
}
let rss = self.network_manager()?.routing_table().route_spec_store(); let rss = self.network_manager()?.routing_table().route_spec_store();
match rss.purge().await { match rss.purge().await {
Ok(_) => Ok("Routes purged".to_owned()), Ok(_) => Ok("Routes purged".to_owned()),
@ -865,12 +869,9 @@ impl VeilidAPI {
} else if arg == "route" { } else if arg == "route" {
self.debug_route(rest).await self.debug_route(rest).await
} else { } else {
Ok(">>> Unknown command\n".to_owned()) Err(VeilidAPIError::generic("Unknown debug command"))
} }
}; };
// if let Ok(res) = &res {
// debug!("{}", res);
// }
res res
} }
} }

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:veilid/veilid.dart'; import 'package:veilid/veilid.dart';
import 'package:loggy/loggy.dart'; import 'package:loggy/loggy.dart';
import 'package:veilid_example/veilid_theme.dart'; import 'package:veilid_example/veilid_theme.dart';
@ -8,6 +9,7 @@ import 'package:veilid_example/veilid_theme.dart';
import 'log_terminal.dart'; import 'log_terminal.dart';
import 'config.dart'; import 'config.dart';
import 'log.dart'; import 'log.dart';
import 'history_wrapper.dart';
// Main App // Main App
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
@ -22,6 +24,8 @@ class _MyAppState extends State<MyApp> with UiLoggy {
bool _startedUp = false; bool _startedUp = false;
Stream<VeilidUpdate>? _updateStream; Stream<VeilidUpdate>? _updateStream;
Future<void>? _updateProcessor; Future<void>? _updateProcessor;
final _debugHistoryWrapper = HistoryWrapper();
String? _errorText;
@override @override
void initState() { void initState() {
@ -136,51 +140,79 @@ class _MyAppState extends State<MyApp> with UiLoggy {
body: Column(children: [ body: Column(children: [
const Expanded(child: LogTerminal()), const Expanded(child: LogTerminal()),
Container( Container(
decoration: BoxDecoration(color: materialPrimaryColor, boxShadow: [ decoration: BoxDecoration(
BoxShadow( color: materialBackgroundColor.shade100,
color: Colors.black.withOpacity(0.15), boxShadow: [
spreadRadius: 4, BoxShadow(
blurRadius: 4, color: Colors.black.withOpacity(0.15),
) spreadRadius: 4,
]), blurRadius: 4,
)
]),
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
child: Row(children: [ child: Row(children: [
Expanded( Expanded(
child: pad(TextField( child: pad(_debugHistoryWrapper.wrap(
decoration: setState,
newInputDecoration('Debug Command', _startedUp), TextField(
textInputAction: TextInputAction.send, controller: _debugHistoryWrapper.controller,
enabled: _startedUp, decoration: newInputDecoration(
onSubmitted: (String v) async { 'Debug Command', _errorText, _startedUp),
loggy.info(await Veilid.instance.debug(v)); textInputAction: TextInputAction.unspecified,
}))), enabled: _startedUp,
pad(const Text('Startup')), onChanged: (v) {
pad(Switch( setState(() {
value: _startedUp, _errorText = null;
onChanged: (bool value) async { });
await toggleStartup(value); },
})), onSubmitted: (String v) async {
pad(DropdownButton<LogLevel>( try {
value: loggy.level.logLevel, var res = await Veilid.instance.debug(v);
onChanged: (LogLevel? newLevel) { loggy.info(res);
setState(() { setState(() {
setRootLogLevel(newLevel); _debugHistoryWrapper.submit(v);
}); });
}, } on VeilidAPIException catch (e) {
items: const [ setState(() {
DropdownMenuItem<LogLevel>( _errorText = e.toDisplayError();
value: LogLevel.error, child: Text("Error")), });
DropdownMenuItem<LogLevel>( }
value: LogLevel.warning, child: Text("Warning")), }),
DropdownMenuItem<LogLevel>( ))),
value: LogLevel.info, child: Text("Info")), pad(
DropdownMenuItem<LogLevel>( Column(children: [
value: LogLevel.debug, child: Text("Debug")), const Text('Startup'),
DropdownMenuItem<LogLevel>( Switch(
value: traceLevel, child: Text("Trace")), value: _startedUp,
DropdownMenuItem<LogLevel>( onChanged: (bool value) async {
value: LogLevel.all, child: Text("All")), await toggleStartup(value);
])), }),
]),
),
pad(Column(children: [
const Text('Log Level'),
DropdownButton<LogLevel>(
value: loggy.level.logLevel,
onChanged: (LogLevel? newLevel) {
setState(() {
setRootLogLevel(newLevel);
});
},
items: const [
DropdownMenuItem<LogLevel>(
value: LogLevel.error, child: Text("Error")),
DropdownMenuItem<LogLevel>(
value: LogLevel.warning, child: Text("Warning")),
DropdownMenuItem<LogLevel>(
value: LogLevel.info, child: Text("Info")),
DropdownMenuItem<LogLevel>(
value: LogLevel.debug, child: Text("Debug")),
DropdownMenuItem<LogLevel>(
value: traceLevel, child: Text("Trace")),
DropdownMenuItem<LogLevel>(
value: LogLevel.all, child: Text("All")),
]),
])),
]), ]),
), ),
])); ]));

View File

@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// TextField History Wrapper
class HistoryWrapper {
final List<String> _history = [];
int _historyPosition = 0;
final _historyTextEditingController = TextEditingController();
String _historyCurrentEdit = "";
TextEditingController get controller {
return _historyTextEditingController;
}
void submit(String v) {
// add to history
if (_history.isEmpty || _history.last != v) {
_history.add(v);
if (_history.length > 100) {
_history.removeAt(0);
}
}
_historyPosition = _history.length;
_historyTextEditingController.text = "";
}
Widget wrap(
void Function(void Function())? stateSetter, TextField textField) {
void Function(void Function()) setState = stateSetter ?? (x) => x();
return KeyboardListener(
onKeyEvent: (KeyEvent event) {
setState(() {
if (event.runtimeType == KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.arrowUp) {
if (_historyPosition > 0) {
if (_historyPosition == _history.length) {
_historyCurrentEdit = _historyTextEditingController.text;
}
_historyPosition -= 1;
_historyTextEditingController.text = _history[_historyPosition];
}
} else if (event.runtimeType == KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.arrowDown) {
if (_historyPosition < _history.length) {
_historyPosition += 1;
if (_historyPosition == _history.length) {
_historyTextEditingController.text = _historyCurrentEdit;
} else {
_historyTextEditingController.text = _history[_historyPosition];
}
}
} else if (event.runtimeType == KeyDownEvent) {
_historyPosition = _history.length;
_historyCurrentEdit = _historyTextEditingController.text;
}
});
},
focusNode: FocusNode(onKey: (FocusNode node, RawKeyEvent event) {
if (event.logicalKey == LogicalKeyboardKey.arrowDown ||
event.logicalKey == LogicalKeyboardKey.arrowUp) {
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
}),
child: textField,
);
}
}

View File

@ -257,29 +257,38 @@ Padding pad(Widget child) {
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// Theme // Theme
InputDecoration newInputDecoration(String labelText, bool enabled) { InputDecoration newInputDecoration(
String labelText, String? errorText, bool enabled) {
return InputDecoration( return InputDecoration(
labelText: labelText, labelText: labelText,
fillColor: enabled errorText: errorText,
? materialPrimaryColor.shade200 filled: !enabled,
: materialPrimaryColor.shade200.withOpacity(0.5)); fillColor: materialPrimaryColor.shade300.withOpacity(0.1));
} }
InputDecorationTheme newInputDecorationTheme() { InputDecorationTheme newInputDecorationTheme() {
return InputDecorationTheme( return InputDecorationTheme(
border: const OutlineInputBorder(), border: OutlineInputBorder(
filled: true,
fillColor: materialPrimaryColor.shade200,
disabledBorder: const OutlineInputBorder(
borderSide: borderSide:
BorderSide(color: Color.fromARGB(0, 0, 0, 0), width: 0.0)), BorderSide(color: materialPrimaryColor.shade300, width: 1.0)),
disabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: materialPrimaryColor.shade600, width: 1.0)),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: borderSide:
BorderSide(color: materialPrimaryColor.shade900, width: 0.0)), BorderSide(color: materialPrimaryColor.shade900, width: 1.0)),
floatingLabelBehavior: FloatingLabelBehavior.never, errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: materialPopColor.shade800, width: 1.0)),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: materialPopColor.shade600, width: 1.0)),
errorStyle: TextStyle(
color: materialPopColor.shade600,
letterSpacing: 1.1,
),
floatingLabelBehavior: FloatingLabelBehavior.auto,
floatingLabelStyle: TextStyle( floatingLabelStyle: TextStyle(
color: materialPrimaryColor.shade900, color: materialPrimaryColor.shade900,
letterSpacing: 1.2, letterSpacing: 1.1,
)); ));
} }

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:html';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:convert'; import 'dart:convert';
@ -1571,6 +1572,8 @@ abstract class VeilidAPIException implements Exception {
} }
} }
} }
String toDisplayError();
} }
class VeilidAPIExceptionNotInitialized implements VeilidAPIException { class VeilidAPIExceptionNotInitialized implements VeilidAPIException {
@ -1578,6 +1581,11 @@ class VeilidAPIExceptionNotInitialized implements VeilidAPIException {
String toString() { String toString() {
return "VeilidAPIException: NotInitialized"; return "VeilidAPIException: NotInitialized";
} }
@override
String toDisplayError() {
return "Not initialized";
}
} }
class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException { class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException {
@ -1585,6 +1593,11 @@ class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException {
String toString() { String toString() {
return "VeilidAPIException: AlreadyInitialized"; return "VeilidAPIException: AlreadyInitialized";
} }
@override
String toDisplayError() {
return "Already initialized";
}
} }
class VeilidAPIExceptionTimeout implements VeilidAPIException { class VeilidAPIExceptionTimeout implements VeilidAPIException {
@ -1592,6 +1605,11 @@ class VeilidAPIExceptionTimeout implements VeilidAPIException {
String toString() { String toString() {
return "VeilidAPIException: Timeout"; return "VeilidAPIException: Timeout";
} }
@override
String toDisplayError() {
return "Timeout";
}
} }
class VeilidAPIExceptionShutdown implements VeilidAPIException { class VeilidAPIExceptionShutdown implements VeilidAPIException {
@ -1599,6 +1617,11 @@ class VeilidAPIExceptionShutdown implements VeilidAPIException {
String toString() { String toString() {
return "VeilidAPIException: Shutdown"; return "VeilidAPIException: Shutdown";
} }
@override
String toDisplayError() {
return "Currently shut down";
}
} }
class VeilidAPIExceptionNodeNotFound implements VeilidAPIException { class VeilidAPIExceptionNodeNotFound implements VeilidAPIException {
@ -1609,6 +1632,11 @@ class VeilidAPIExceptionNodeNotFound implements VeilidAPIException {
return "VeilidAPIException: NodeNotFound (nodeId: $nodeId)"; return "VeilidAPIException: NodeNotFound (nodeId: $nodeId)";
} }
@override
String toDisplayError() {
return "Node node found: $nodeId";
}
// //
VeilidAPIExceptionNodeNotFound(this.nodeId); VeilidAPIExceptionNodeNotFound(this.nodeId);
} }
@ -1621,6 +1649,11 @@ class VeilidAPIExceptionNoDialInfo implements VeilidAPIException {
return "VeilidAPIException: NoDialInfo (nodeId: $nodeId)"; return "VeilidAPIException: NoDialInfo (nodeId: $nodeId)";
} }
@override
String toDisplayError() {
return "No dial info: $nodeId";
}
// //
VeilidAPIExceptionNoDialInfo(this.nodeId); VeilidAPIExceptionNoDialInfo(this.nodeId);
} }
@ -1633,6 +1666,11 @@ class VeilidAPIExceptionInternal implements VeilidAPIException {
return "VeilidAPIException: Internal ($message)"; return "VeilidAPIException: Internal ($message)";
} }
@override
String toDisplayError() {
return "Internal error: $message";
}
// //
VeilidAPIExceptionInternal(this.message); VeilidAPIExceptionInternal(this.message);
} }
@ -1645,6 +1683,11 @@ class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
return "VeilidAPIException: Unimplemented ($message)"; return "VeilidAPIException: Unimplemented ($message)";
} }
@override
String toDisplayError() {
return "Unimplemented: $message";
}
// //
VeilidAPIExceptionUnimplemented(this.message); VeilidAPIExceptionUnimplemented(this.message);
} }
@ -1658,6 +1701,11 @@ class VeilidAPIExceptionParseError implements VeilidAPIException {
return "VeilidAPIException: ParseError ($message)\n value: $value"; return "VeilidAPIException: ParseError ($message)\n value: $value";
} }
@override
String toDisplayError() {
return "Parse error: $message";
}
// //
VeilidAPIExceptionParseError(this.message, this.value); VeilidAPIExceptionParseError(this.message, this.value);
} }
@ -1672,6 +1720,11 @@ class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
return "VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value"; return "VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value";
} }
@override
String toDisplayError() {
return "Invalid argument for $context: $argument";
}
// //
VeilidAPIExceptionInvalidArgument(this.context, this.argument, this.value); VeilidAPIExceptionInvalidArgument(this.context, this.argument, this.value);
} }
@ -1685,6 +1738,11 @@ class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
return "VeilidAPIException: MissingArgument ($context:$argument)"; return "VeilidAPIException: MissingArgument ($context:$argument)";
} }
@override
String toDisplayError() {
return "Missing argument for $context: $argument";
}
// //
VeilidAPIExceptionMissingArgument(this.context, this.argument); VeilidAPIExceptionMissingArgument(this.context, this.argument);
} }
@ -1697,6 +1755,11 @@ class VeilidAPIExceptionGeneric implements VeilidAPIException {
return "VeilidAPIException: Generic (message: $message)"; return "VeilidAPIException: Generic (message: $message)";
} }
@override
String toDisplayError() {
return message;
}
// //
VeilidAPIExceptionGeneric(this.message); VeilidAPIExceptionGeneric(this.message);
} }