feat(editor): localised analyzer/strip/run messages + monospace font fallback
Closes operator-reported issues around the text-tab font and
the English-only run + diagnostic surfaces.
- **Real monospace everywhere**. The package never bundled
JetBrains Mono as an asset (it relied on Studio's
google_fonts pre-load), so a host that doesn't ship the
font saw the YAML editor render in the system proportional
default. New _monoTextStyle() pins fontFamilyFallback to a
cross-platform monospace chain (Menlo / Consolas / Courier
New / monospace) so the editor stays a grid in every host.
Applied to the code field, gutter, diagnostic strip,
issue rows, hover card, fix buttons, and the run tab's
error box.
- **Locale-aware analyzer messages**. New AnalyzerStrings
adapter holds every string the analyzer emits, with an
.english default + an .from(FlowEditorStrings) factory.
FlowYamlCodeController.setCapabilityProviders takes the
strings; FlowEditorPage wires them from the active locale.
The analyzer's 'Unknown capability', 'Did you mean',
'Not in the store — install locally with fai install
--link', 'Unknown input/output type', YAML parse errors,
and every quick-fix label (Install / Add source / Use /
Change to) now flip to DE when the editor's locale is DE.
- **Localised run + diagnostic chrome**. The bottom strip's
'No issues', '2 errors · 1 warning', 'Copy all'; the
issue row's L-prefix + Copy tooltip; the hover card's
L-prefix + Copy tooltip; the run-block tooltip + inline
message ('2 Fehler verhindern den Lauf · siehe
Diagnose-Leiste unten'); the step-row 'awaiting approval'
suffix; the CopyableErrorBox's Copy / Copied tooltip —
all now flow through FlowEditorStrings.
Bumped to 0.20.0.
Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
parent
b6bb8741a9
commit
5cd2745db5
6 changed files with 306 additions and 97 deletions
|
|
@ -20,6 +20,7 @@
|
|||
import 'package:flutter_code_editor/flutter_code_editor.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
import 'l10n.dart';
|
||||
import 'quick_fix.dart';
|
||||
import 'wire_colors.dart';
|
||||
|
||||
|
|
@ -59,9 +60,15 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
/// [kOutputsNodeId] sentinels.
|
||||
final Map<String, IssueType> _stepSeverity = {};
|
||||
|
||||
/// Localised string builders the analyzer pipes its messages
|
||||
/// through. Default is English so the analyzer behaves the
|
||||
/// same in tests + host-less callers.
|
||||
final AnalyzerStrings strings;
|
||||
|
||||
FlowAnalyzer({
|
||||
required this.availableCapabilities,
|
||||
this.storeCapabilities,
|
||||
this.strings = AnalyzerStrings.english,
|
||||
});
|
||||
|
||||
/// Read-only view of the fixes computed during the last
|
||||
|
|
@ -115,14 +122,18 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
issues.add(
|
||||
Issue(
|
||||
line: e.span?.start.line ?? 0,
|
||||
message: 'YAML: ${e.message}',
|
||||
message: strings.yamlError(e.message),
|
||||
type: IssueType.error,
|
||||
),
|
||||
);
|
||||
return AnalysisResult(issues: issues);
|
||||
} catch (e) {
|
||||
issues.add(
|
||||
Issue(line: 0, message: 'YAML: $e', type: IssueType.error),
|
||||
Issue(
|
||||
line: 0,
|
||||
message: strings.yamlError(e.toString()),
|
||||
type: IssueType.error,
|
||||
),
|
||||
);
|
||||
return AnalysisResult(issues: issues);
|
||||
}
|
||||
|
|
@ -159,16 +170,12 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
// Tailor the message: "unknown" reads identical in
|
||||
// both cases, but the recovery line nudges toward
|
||||
// the right action.
|
||||
// the right action. Localised via [strings].
|
||||
final message = inStore
|
||||
? 'Unknown capability "$useValue". '
|
||||
'Install via the Fix button or check the spelling.'
|
||||
? strings.unknownCapInStore(useValue)
|
||||
: didYouMean != null
|
||||
? 'Unknown capability "$useValue". '
|
||||
'Did you mean "$didYouMean"?'
|
||||
: 'Unknown capability "$useValue". '
|
||||
'Not in the store — install locally with '
|
||||
'`fai install --link <path>` or check the spelling.';
|
||||
? strings.unknownCapTypo(useValue, didYouMean)
|
||||
: strings.unknownCapNotInStore(useValue);
|
||||
final issue = Issue(
|
||||
line: issueLine,
|
||||
message: message,
|
||||
|
|
@ -192,7 +199,7 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
ReplaceLineValueFix(
|
||||
line: issueLine,
|
||||
replacement: fullReplacement,
|
||||
label: 'Use "$fullReplacement"',
|
||||
label: strings.fixUseInstead(fullReplacement),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -200,20 +207,14 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
fixes.add(
|
||||
InstallCapabilityFix(
|
||||
capability: useValue,
|
||||
label: 'Install $useValue',
|
||||
label: strings.fixInstallCap(useValue),
|
||||
),
|
||||
);
|
||||
} else if (didYouMean == null) {
|
||||
// Not in store + no near-miss spelling — give the
|
||||
// operator a path to register the module they
|
||||
// actually have (local clone, internal URL, …).
|
||||
// Hidden behind the "Did you mean" suggestion when
|
||||
// present so the suggested fix stays the primary
|
||||
// action.
|
||||
fixes.add(
|
||||
AddModuleSourceFix(
|
||||
capability: useValue,
|
||||
label: 'Add source for $useValue…',
|
||||
label: strings.fixAddSource(useValue),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -226,13 +227,13 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
_checkFieldTypes(
|
||||
doc['inputs'],
|
||||
'input',
|
||||
strings.inputKind(),
|
||||
issues,
|
||||
nodeId: kInputsNodeId,
|
||||
);
|
||||
_checkFieldTypes(
|
||||
doc['outputs'],
|
||||
'output',
|
||||
strings.outputKind(),
|
||||
issues,
|
||||
nodeId: kOutputsNodeId,
|
||||
);
|
||||
|
|
@ -278,23 +279,22 @@ class FlowAnalyzer extends AbstractAnalyzer {
|
|||
if (!kKnownTypes.contains(value)) {
|
||||
final issue = Issue(
|
||||
line: entry.value.span.start.line,
|
||||
message:
|
||||
'Unknown $kind type "$value". '
|
||||
'Use one of: ${kKnownTypes.join(", ")}.',
|
||||
message: strings.unknownType(
|
||||
kind,
|
||||
value,
|
||||
kKnownTypes.join(", "),
|
||||
),
|
||||
type: IssueType.warning,
|
||||
);
|
||||
out.add(issue);
|
||||
_bumpSeverity(nodeId, IssueType.warning);
|
||||
// If the typo is within edit-distance two of a known
|
||||
// type token, offer a one-click replace as the primary
|
||||
// fix. The strip and tooltip render this as a button.
|
||||
final closest = _closestKnownType(value);
|
||||
if (closest != null) {
|
||||
_fixesByIssue[issue] = [
|
||||
ReplaceLineValueFix(
|
||||
line: entry.value.span.start.line,
|
||||
replacement: closest,
|
||||
label: 'Change to "$closest"',
|
||||
label: strings.fixChangeTo(closest),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue