Update localization files and improve path map UI

- Added new localization strings for Swedish, Ukrainian, and Chinese languages in app_sv.arb, app_uk.arb, and app_zh.arb respectively.
- Enhanced the path map UI in channel_message_path_screen.dart for better readability and interaction.
- Improved message retry logic in message_retry_service.dart to prevent double-pumping of queues.
- Bumped version number in pubspec.yaml to 9.5.0+13.
- Cleared untranslated strings in untranslated.json to reflect current localization status.
This commit is contained in:
zjs81
2026-06-13 01:58:42 -07:00
parent 815534d409
commit 760d8e1db3
39 changed files with 8823 additions and 7212 deletions
+115 -93
View File
@@ -1466,114 +1466,136 @@ class _ChannelMessagePathMapScreenState
border: Border.all(color: MeshPalette.line2),
),
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 4, 0),
child: Row(
child: DefaultTextStyle(
style: const TextStyle(color: MeshPalette.ink),
child: IconTheme(
data: const IconThemeData(color: MeshPalette.ink),
child: TextButtonTheme(
data: TextButtonThemeData(
style: TextButton.styleFrom(foregroundColor: MeshPalette.ink),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 4, 0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
l10n.channelPath_repeaterHops,
style: const TextStyle(
fontWeight: FontWeight.w600,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
l10n.channelPath_repeaterHops,
style: const TextStyle(
fontWeight: FontWeight.w600,
),
),
),
Text(
formatDistance(
selectedDisplay?.distanceMeters ??
_pathDistance,
isImperial: isImperial,
),
style: MeshTheme.mono(
fontSize: 12,
color: MeshPalette.ink2,
),
),
],
),
),
Text(
formatDistance(
selectedDisplay?.distanceMeters ??
_pathDistance,
isImperial: isImperial,
const SizedBox(height: 4),
PathMiniLegend(
combined: combined,
showInferred: false,
),
style: MeshTheme.mono(
fontSize: 12,
color: MeshPalette.ink2,
),
),
],
],
),
),
const SizedBox(height: 4),
PathMiniLegend(
combined: combined,
showInferred: false,
IconButton(
visualDensity: VisualDensity.compact,
icon: Icon(
_panelCollapsed
? Icons.expand_less
: Icons.expand_more,
size: 20,
),
tooltip: _panelCollapsed
? l10n.pathMap_expandPanel
: l10n.pathMap_collapsePanel,
onPressed: () => setState(
() => _panelCollapsed = !_panelCollapsed,
),
),
],
),
),
IconButton(
visualDensity: VisualDensity.compact,
icon: Icon(
_panelCollapsed ? Icons.expand_less : Icons.expand_more,
size: 20,
),
tooltip: _panelCollapsed
? l10n.pathMap_expandPanel
: l10n.pathMap_collapsePanel,
onPressed: () =>
setState(() => _panelCollapsed = !_panelCollapsed),
PathAnimationControls(
playback: _playback,
selected: selectedDisplay,
animationEnabled: _animationEnabled,
onToggleAnimation: () => setState(() {
_animationEnabled = !_animationEnabled;
if (!_animationEnabled) _playback.stop();
}),
followEnabled: _followPacket,
onToggleFollow: _toggleFollowPacket,
),
if (!_panelCollapsed) ...[
if (selectedDisplay != null &&
selectedDisplay.unresolvedHops > 0)
Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 4),
child: Text(
l10n.pathMap_partialAnimation(
selectedDisplay.unresolvedHops,
),
style: TextStyle(
fontSize: 10.5,
color: MeshPalette.warn,
),
),
),
if (combined)
PathSummaryList(
paths: entries.map((e) => e.display).toList(),
selectedId: selectedDisplay?.id ?? '',
hiddenIds: _hiddenPathIds,
isImperial: isImperial,
onSelect: (display) {
for (final entry in entries) {
if (entry.display.id == display.id) {
_selectEntry(entry);
break;
}
}
},
onToggleVisibility: (display) =>
_togglePathVisibility(
display,
entries,
selectedDisplay,
),
onShowAll: () => setState(_hiddenPathIds.clear),
),
const Divider(height: 1),
Expanded(
child: _buildHopListView(
hops,
selectedDisplay,
hopUseCount,
),
),
],
],
),
),
PathAnimationControls(
playback: _playback,
selected: selectedDisplay,
animationEnabled: _animationEnabled,
onToggleAnimation: () => setState(() {
_animationEnabled = !_animationEnabled;
if (!_animationEnabled) _playback.stop();
}),
followEnabled: _followPacket,
onToggleFollow: _toggleFollowPacket,
),
if (!_panelCollapsed) ...[
if (selectedDisplay != null &&
selectedDisplay.unresolvedHops > 0)
Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 4),
child: Text(
l10n.pathMap_partialAnimation(
selectedDisplay.unresolvedHops,
),
style: TextStyle(fontSize: 10.5, color: MeshPalette.warn),
),
),
if (combined)
PathSummaryList(
paths: entries.map((e) => e.display).toList(),
selectedId: selectedDisplay?.id ?? '',
hiddenIds: _hiddenPathIds,
isImperial: isImperial,
onSelect: (display) {
for (final entry in entries) {
if (entry.display.id == display.id) {
_selectEntry(entry);
break;
}
}
},
onToggleVisibility: (display) => _togglePathVisibility(
display,
entries,
selectedDisplay,
),
onShowAll: () => setState(_hiddenPathIds.clear),
),
const Divider(height: 1),
Expanded(
child: _buildHopListView(hops, selectedDisplay, hopUseCount),
),
],
],
),
),
),
),