Collapsable description
This commit is contained in:
parent
7728498bf9
commit
091dd9d4ec
5 changed files with 61 additions and 32 deletions
3
Makefile
3
Makefile
|
|
@ -30,3 +30,6 @@ run-linux-debug-native: build-linux-debug-container
|
|||
|
||||
run-web-debug-native: build-web-debug-container
|
||||
cd build/web && python3 -m http.server $${WEB_PORT:-8081}
|
||||
|
||||
ai:
|
||||
qwen --prompt-interactive --yolo "Read CLAUDE.md. Implement first task not already done in TODO.md"
|
||||
|
|
|
|||
4
TODO.md
4
TODO.md
|
|
@ -1,7 +1,8 @@
|
|||
[ ] Means not done
|
||||
[x] Means done
|
||||
|
||||
- [ ] Unify error reporting. Create class ErrorHandler that get notified of every catched exception. This class prints the exception in stdout.
|
||||
- [X] Unify error reporting. Create class ErrorHandler that get notified of every catched exception. This class prints the exception in stdout.
|
||||
- [ ] Make formula description collapsable in FormulaScreen. Initialy, the description is visible, but the user can hide it.
|
||||
- Refactor formula and unit loading:
|
||||
- [ ] Create method `List<Object?> parseD4rtLiteral(String arrayStringLiteral). It parses a d4rt array literal (containing maps and arrays) to a List<Object?> using d4rt
|
||||
- [ ] Remove `fromArrayStringLiteral` from UnitSpec and Formula.
|
||||
|
|
@ -20,3 +21,4 @@
|
|||
- [ ] From now on, the corpus will be loaded from database instead of assets
|
||||
- [ ] Create method List<UnitSpec> Corpus.withDependencies(Formula formula). It will return the list of units of the formula, and related units from the corpus.
|
||||
- [ ] Add a Share button to the formula list. It will export the array string literal of the formula with the units from Corpus.withDependencies().
|
||||
- [ ] Replace flutter-markdown with flutter-markdown-plus
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
final Map<String, String?> _selectedValues = {}; // for string dropdowns
|
||||
String? _result;
|
||||
String? _selectedOutputUnit;
|
||||
bool _isDescriptionExpanded = true; // Track description expansion state
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -194,36 +195,45 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
child: ExpansionTile(
|
||||
title: Text(
|
||||
'Description',
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
child: MarkdownBody(
|
||||
data: widget.formula.description!,
|
||||
shrinkWrap: true,
|
||||
builders: {
|
||||
'latex': LatexElementBuilder(),
|
||||
},
|
||||
extensionSet: markdown.ExtensionSet(
|
||||
[LatexBlockSyntax()],
|
||||
[LatexInlineSyntax()],
|
||||
),
|
||||
initiallyExpanded: _isDescriptionExpanded,
|
||||
onExpansionChanged: (bool expanded) {
|
||||
setState(() {
|
||||
_isDescriptionExpanded = expanded;
|
||||
});
|
||||
},
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: MarkdownBody(
|
||||
data: widget.formula.description!,
|
||||
shrinkWrap: true,
|
||||
builders: {
|
||||
'latex': LatexElementBuilder(),
|
||||
},
|
||||
extensionSet: markdown.ExtensionSet(
|
||||
[LatexBlockSyntax()],
|
||||
[LatexInlineSyntax()],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,16 +14,30 @@ class ErrorHandler {
|
|||
// Print the exception to stdout as requested
|
||||
print('ErrorHandler caught exception:');
|
||||
print(error);
|
||||
|
||||
|
||||
if (stackTrace != null) {
|
||||
print('Stack trace:');
|
||||
print(stackTrace);
|
||||
}
|
||||
|
||||
|
||||
// Call the custom error handler if provided
|
||||
onError?.call(error, stackTrace);
|
||||
}
|
||||
|
||||
/// Convenience method to wrap code that might throw exceptions
|
||||
T handleError<T>(T Function() operation, {T? defaultValue}) {
|
||||
try {
|
||||
return operation();
|
||||
} catch (error, stackTrace) {
|
||||
notify(error, stackTrace);
|
||||
|
||||
if (defaultValue != null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Global instance of ErrorHandler for easy access
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ void main() {
|
|||
errors.add(error);
|
||||
};
|
||||
|
||||
int result = errorHandler.handleError(() => 42, defaultValue: 0);
|
||||
int result = ErrorHandler().handleError(() => 42, defaultValue: 0);
|
||||
expect(result, 42);
|
||||
|
||||
result = errorHandler.handleError(() {
|
||||
result = ErrorHandler().handleError(() {
|
||||
throw Exception('Handled exception');
|
||||
}, defaultValue: 100);
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ void main() {
|
|||
};
|
||||
|
||||
expect(() {
|
||||
errorHandler.handleError(() {
|
||||
ErrorHandler().handleError(() {
|
||||
throw Exception('Rethrown exception');
|
||||
});
|
||||
}, throwsA(const TypeMatcher<Exception>()));
|
||||
|
|
|
|||
Loading…
Reference in a new issue