format files

This commit is contained in:
zjs81
2026-06-13 00:39:13 -07:00
parent 7da4e68384
commit becfbedc99
26 changed files with 1040 additions and 741 deletions
+139 -168
View File
@@ -30,87 +30,103 @@ class AppSettingsScreen extends StatelessWidget {
), ),
body: SafeArea( body: SafeArea(
top: false, top: false,
child: Consumer3<AppSettingsService, MeshCoreConnector, child:
TranslationService>( Consumer3<
builder: ( AppSettingsService,
context, MeshCoreConnector,
settingsService, TranslationService
connector, >(
translationService, builder:
child, (
) {
return ListView(
padding: const EdgeInsets.fromLTRB(0, 8, 0, 24),
children: [
// APPEARANCE
SectionHeader(context.l10n.appSettings_appearance),
MeshCard(
padding: EdgeInsets.zero,
child: _buildAppearanceContent(context, settingsService),
),
// NOTIFICATIONS
SectionHeader(context.l10n.appSettings_notifications),
MeshCard(
padding: EdgeInsets.zero,
child: _buildNotificationsContent(context, settingsService),
),
// MESSAGING
SectionHeader(context.l10n.appSettings_messaging),
MeshCard(
padding: EdgeInsets.zero,
child: _buildMessagingContent(context, settingsService),
),
// BATTERY
SectionHeader(context.l10n.appSettings_battery),
MeshCard(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
child: _buildBatteryContent(
context, context,
settingsService, settingsService,
connector, connector,
), translationService,
), child,
) {
return ListView(
padding: const EdgeInsets.fromLTRB(0, 8, 0, 24),
children: [
// APPEARANCE
SectionHeader(context.l10n.appSettings_appearance),
MeshCard(
padding: EdgeInsets.zero,
child: _buildAppearanceContent(
context,
settingsService,
),
),
// MAP // NOTIFICATIONS
SectionHeader(context.l10n.appSettings_mapDisplay), SectionHeader(context.l10n.appSettings_notifications),
MeshCard( MeshCard(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
child: _buildMapContent(context, settingsService), child: _buildNotificationsContent(
), context,
settingsService,
),
),
// TRANSLATION (non-web only) // MESSAGING
if (!kIsWeb) ...[ SectionHeader(context.l10n.appSettings_messaging),
SectionHeader(context.l10n.translation_title), MeshCard(
MeshCard( padding: EdgeInsets.zero,
padding: EdgeInsets.zero, child: _buildMessagingContent(
child: _buildTranslationContent( context,
context, settingsService,
settingsService, ),
translationService, ),
),
),
],
// CYR2LAT // BATTERY
SectionHeader(context.l10n.channels_cyr2latSettingsHeading), SectionHeader(context.l10n.appSettings_battery),
MeshCard( MeshCard(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 16), padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
child: _buildCyr2LatContent(context, settingsService), child: _buildBatteryContent(
), context,
settingsService,
connector,
),
),
// DEBUG // MAP
SectionHeader(context.l10n.appSettings_debugCard), SectionHeader(context.l10n.appSettings_mapDisplay),
MeshCard( MeshCard(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
child: _buildDebugContent(context, settingsService), child: _buildMapContent(context, settingsService),
), ),
],
); // TRANSLATION (non-web only)
}, if (!kIsWeb) ...[
), SectionHeader(context.l10n.translation_title),
MeshCard(
padding: EdgeInsets.zero,
child: _buildTranslationContent(
context,
settingsService,
translationService,
),
),
],
// CYR2LAT
SectionHeader(
context.l10n.channels_cyr2latSettingsHeading,
),
MeshCard(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
child: _buildCyr2LatContent(context, settingsService),
),
// DEBUG
SectionHeader(context.l10n.appSettings_debugCard),
MeshCard(
padding: EdgeInsets.zero,
child: _buildDebugContent(context, settingsService),
),
],
);
},
),
), ),
); );
} }
@@ -317,8 +333,7 @@ class AppSettingsScreen extends StatelessWidget {
), ),
value: settingsService.settings.notifyOnNewChannelMessage, value: settingsService.settings.notifyOnNewChannelMessage,
onChanged: notifEnabled onChanged: notifEnabled
? (value) => ? (value) => settingsService.setNotifyOnNewChannelMessage(value)
settingsService.setNotifyOnNewChannelMessage(value)
: null, : null,
), ),
const Divider(height: 1, indent: 16), const Divider(height: 1, indent: 16),
@@ -367,9 +382,7 @@ class AppSettingsScreen extends StatelessWidget {
), ),
secondary: const Icon(Icons.refresh_outlined, size: 20), secondary: const Icon(Icons.refresh_outlined, size: 20),
title: Text(context.l10n.appSettings_clearPathOnMaxRetry), title: Text(context.l10n.appSettings_clearPathOnMaxRetry),
subtitle: Text( subtitle: Text(context.l10n.appSettings_clearPathOnMaxRetrySubtitle),
context.l10n.appSettings_clearPathOnMaxRetrySubtitle,
),
value: settingsService.settings.clearPathOnMaxRetry, value: settingsService.settings.clearPathOnMaxRetry,
onChanged: (value) { onChanged: (value) {
settingsService.setClearPathOnMaxRetry(value); settingsService.setClearPathOnMaxRetry(value);
@@ -472,9 +485,7 @@ class AppSettingsScreen extends StatelessWidget {
min: 0.5, min: 0.5,
max: 5.0, max: 5.0,
divisions: 9, divisions: 9,
label: settingsService label: settingsService.settings.initialRouteWeight
.settings
.initialRouteWeight
.toStringAsFixed(1), .toStringAsFixed(1),
onChanged: (value) => onChanged: (value) =>
settingsService.setInitialRouteWeight(value), settingsService.setInitialRouteWeight(value),
@@ -485,9 +496,7 @@ class AppSettingsScreen extends StatelessWidget {
const Divider(height: 1), const Divider(height: 1),
ListTile( ListTile(
title: Text( title: Text(
context context.l10n.appSettings_routeWeightSuccessIncrement,
.l10n
.appSettings_routeWeightSuccessIncrement,
), ),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -517,9 +526,7 @@ class AppSettingsScreen extends StatelessWidget {
const Divider(height: 1), const Divider(height: 1),
ListTile( ListTile(
title: Text( title: Text(
context context.l10n.appSettings_routeWeightFailureDecrement,
.l10n
.appSettings_routeWeightFailureDecrement,
), ),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -548,9 +555,7 @@ class AppSettingsScreen extends StatelessWidget {
), ),
const Divider(height: 1), const Divider(height: 1),
ListTile( ListTile(
title: Text( title: Text(context.l10n.appSettings_maxMessageRetries),
context.l10n.appSettings_maxMessageRetries,
),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@@ -560,16 +565,12 @@ class AppSettingsScreen extends StatelessWidget {
.appSettings_maxMessageRetriesSubtitle, .appSettings_maxMessageRetriesSubtitle,
), ),
Slider( Slider(
value: settingsService value: settingsService.settings.maxMessageRetries
.settings
.maxMessageRetries
.toDouble(), .toDouble(),
min: 2, min: 2,
max: 10, max: 10,
divisions: 8, divisions: 8,
label: settingsService label: settingsService.settings.maxMessageRetries
.settings
.maxMessageRetries
.toString(), .toString(),
onChanged: (value) => settingsService onChanged: (value) => settingsService
.setMaxMessageRetries(value.toInt()), .setMaxMessageRetries(value.toInt()),
@@ -590,9 +591,7 @@ class AppSettingsScreen extends StatelessWidget {
), ),
secondary: const Icon(Icons.location_searching, size: 20), secondary: const Icon(Icons.location_searching, size: 20),
title: Text(context.l10n.appSettings_enableMessageTracing), title: Text(context.l10n.appSettings_enableMessageTracing),
subtitle: Text( subtitle: Text(context.l10n.appSettings_enableMessageTracingSubtitle),
context.l10n.appSettings_enableMessageTracingSubtitle,
),
value: settingsService.settings.enableMessageTracing, value: settingsService.settings.enableMessageTracing,
onChanged: (value) { onChanged: (value) {
settingsService.setEnableMessageTracing(value); settingsService.setEnableMessageTracing(value);
@@ -765,9 +764,7 @@ class AppSettingsScreen extends StatelessWidget {
settingsService.settings.mapTimeFilterHours == 0 settingsService.settings.mapTimeFilterHours == 0
? context.l10n.appSettings_timeFilterShowAll ? context.l10n.appSettings_timeFilterShowAll
: context.l10n.appSettings_timeFilterShowLast( : context.l10n.appSettings_timeFilterShowLast(
settingsService settingsService.settings.mapTimeFilterHours
.settings
.mapTimeFilterHours
.toInt(), .toInt(),
), ),
style: textTheme.bodySmall?.copyWith( style: textTheme.bodySmall?.copyWith(
@@ -925,15 +922,17 @@ class AppSettingsScreen extends StatelessWidget {
title: Text( title: Text(
context.l10n.translation_autoIncomingTitle, context.l10n.translation_autoIncomingTitle,
style: TextStyle( style: TextStyle(
color: color: translationEnabled
translationEnabled ? null : Theme.of(context).disabledColor, ? null
: Theme.of(context).disabledColor,
), ),
), ),
subtitle: Text( subtitle: Text(
context.l10n.translation_autoIncomingSubtitle, context.l10n.translation_autoIncomingSubtitle,
style: TextStyle( style: TextStyle(
color: color: translationEnabled
translationEnabled ? null : Theme.of(context).disabledColor, ? null
: Theme.of(context).disabledColor,
), ),
), ),
value: settings.autoTranslateIncomingMessages, value: settings.autoTranslateIncomingMessages,
@@ -955,15 +954,17 @@ class AppSettingsScreen extends StatelessWidget {
title: Text( title: Text(
context.l10n.translation_composerTitle, context.l10n.translation_composerTitle,
style: TextStyle( style: TextStyle(
color: color: translationEnabled
translationEnabled ? null : Theme.of(context).disabledColor, ? null
: Theme.of(context).disabledColor,
), ),
), ),
subtitle: Text( subtitle: Text(
context.l10n.translation_composerSubtitle, context.l10n.translation_composerSubtitle,
style: TextStyle( style: TextStyle(
color: color: translationEnabled
translationEnabled ? null : Theme.of(context).disabledColor, ? null
: Theme.of(context).disabledColor,
), ),
), ),
value: settings.composerTranslationEnabled, value: settings.composerTranslationEnabled,
@@ -973,17 +974,12 @@ class AppSettingsScreen extends StatelessWidget {
), ),
const Divider(height: 1, indent: 16), const Divider(height: 1, indent: 16),
InkWell( InkWell(
onTap: () => onTap: () => _showTranslationLanguageDialog(context, settingsService),
_showTranslationLanguageDialog(context, settingsService),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row( child: Row(
children: [ children: [
Icon( Icon(Icons.language, size: 20, color: scheme.onSurfaceVariant),
Icons.language,
size: 20,
color: scheme.onSurfaceVariant,
),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Column( child: Column(
@@ -1106,7 +1102,8 @@ class AppSettingsScreen extends StatelessWidget {
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(2), borderRadius: BorderRadius.circular(2),
child: LinearProgressIndicator( child: LinearProgressIndicator(
value: translationService.downloadFileName == value:
translationService.downloadFileName ==
'Merging chunks...' 'Merging chunks...'
? null ? null
: translationService.downloadProgress, : translationService.downloadProgress,
@@ -1151,8 +1148,7 @@ class AppSettingsScreen extends StatelessWidget {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: InkWell( child: InkWell(
borderRadius: borderRadius: BorderRadius.circular(MeshRadii.xs),
BorderRadius.circular(MeshRadii.xs),
onTap: () => settingsService onTap: () => settingsService
.setTranslationSelectedModelId(model.id), .setTranslationSelectedModelId(model.id),
child: Column( child: Column(
@@ -1194,9 +1190,7 @@ class AppSettingsScreen extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
translationService.lastError!, translationService.lastError!,
style: TextStyle( style: TextStyle(color: Theme.of(context).colorScheme.error),
color: Theme.of(context).colorScheme.error,
),
), ),
], ],
], ],
@@ -1373,8 +1367,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageEn, label: context.l10n.appSettings_languageEn,
value: 'en', value: 'en',
selected: selected: settingsService.settings.languageOverride == 'en',
settingsService.settings.languageOverride == 'en',
onTap: () { onTap: () {
settingsService.setLanguageOverride('en'); settingsService.setLanguageOverride('en');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1384,8 +1377,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageFr, label: context.l10n.appSettings_languageFr,
value: 'fr', value: 'fr',
selected: selected: settingsService.settings.languageOverride == 'fr',
settingsService.settings.languageOverride == 'fr',
onTap: () { onTap: () {
settingsService.setLanguageOverride('fr'); settingsService.setLanguageOverride('fr');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1395,8 +1387,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageEs, label: context.l10n.appSettings_languageEs,
value: 'es', value: 'es',
selected: selected: settingsService.settings.languageOverride == 'es',
settingsService.settings.languageOverride == 'es',
onTap: () { onTap: () {
settingsService.setLanguageOverride('es'); settingsService.setLanguageOverride('es');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1406,8 +1397,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageDe, label: context.l10n.appSettings_languageDe,
value: 'de', value: 'de',
selected: selected: settingsService.settings.languageOverride == 'de',
settingsService.settings.languageOverride == 'de',
onTap: () { onTap: () {
settingsService.setLanguageOverride('de'); settingsService.setLanguageOverride('de');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1417,8 +1407,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languagePl, label: context.l10n.appSettings_languagePl,
value: 'pl', value: 'pl',
selected: selected: settingsService.settings.languageOverride == 'pl',
settingsService.settings.languageOverride == 'pl',
onTap: () { onTap: () {
settingsService.setLanguageOverride('pl'); settingsService.setLanguageOverride('pl');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1428,8 +1417,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageSl, label: context.l10n.appSettings_languageSl,
value: 'sl', value: 'sl',
selected: selected: settingsService.settings.languageOverride == 'sl',
settingsService.settings.languageOverride == 'sl',
onTap: () { onTap: () {
settingsService.setLanguageOverride('sl'); settingsService.setLanguageOverride('sl');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1439,8 +1427,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languagePt, label: context.l10n.appSettings_languagePt,
value: 'pt', value: 'pt',
selected: selected: settingsService.settings.languageOverride == 'pt',
settingsService.settings.languageOverride == 'pt',
onTap: () { onTap: () {
settingsService.setLanguageOverride('pt'); settingsService.setLanguageOverride('pt');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1450,8 +1437,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageIt, label: context.l10n.appSettings_languageIt,
value: 'it', value: 'it',
selected: selected: settingsService.settings.languageOverride == 'it',
settingsService.settings.languageOverride == 'it',
onTap: () { onTap: () {
settingsService.setLanguageOverride('it'); settingsService.setLanguageOverride('it');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1461,8 +1447,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageZh, label: context.l10n.appSettings_languageZh,
value: 'zh', value: 'zh',
selected: selected: settingsService.settings.languageOverride == 'zh',
settingsService.settings.languageOverride == 'zh',
onTap: () { onTap: () {
settingsService.setLanguageOverride('zh'); settingsService.setLanguageOverride('zh');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1472,8 +1457,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageSv, label: context.l10n.appSettings_languageSv,
value: 'sv', value: 'sv',
selected: selected: settingsService.settings.languageOverride == 'sv',
settingsService.settings.languageOverride == 'sv',
onTap: () { onTap: () {
settingsService.setLanguageOverride('sv'); settingsService.setLanguageOverride('sv');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1483,8 +1467,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageNl, label: context.l10n.appSettings_languageNl,
value: 'nl', value: 'nl',
selected: selected: settingsService.settings.languageOverride == 'nl',
settingsService.settings.languageOverride == 'nl',
onTap: () { onTap: () {
settingsService.setLanguageOverride('nl'); settingsService.setLanguageOverride('nl');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1494,8 +1477,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageSk, label: context.l10n.appSettings_languageSk,
value: 'sk', value: 'sk',
selected: selected: settingsService.settings.languageOverride == 'sk',
settingsService.settings.languageOverride == 'sk',
onTap: () { onTap: () {
settingsService.setLanguageOverride('sk'); settingsService.setLanguageOverride('sk');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1505,8 +1487,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageBg, label: context.l10n.appSettings_languageBg,
value: 'bg', value: 'bg',
selected: selected: settingsService.settings.languageOverride == 'bg',
settingsService.settings.languageOverride == 'bg',
onTap: () { onTap: () {
settingsService.setLanguageOverride('bg'); settingsService.setLanguageOverride('bg');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1516,8 +1497,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageRu, label: context.l10n.appSettings_languageRu,
value: 'ru', value: 'ru',
selected: selected: settingsService.settings.languageOverride == 'ru',
settingsService.settings.languageOverride == 'ru',
onTap: () { onTap: () {
settingsService.setLanguageOverride('ru'); settingsService.setLanguageOverride('ru');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1527,8 +1507,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageUk, label: context.l10n.appSettings_languageUk,
value: 'uk', value: 'uk',
selected: selected: settingsService.settings.languageOverride == 'uk',
settingsService.settings.languageOverride == 'uk',
onTap: () { onTap: () {
settingsService.setLanguageOverride('uk'); settingsService.setLanguageOverride('uk');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1538,8 +1517,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageHu, label: context.l10n.appSettings_languageHu,
value: 'hu', value: 'hu',
selected: selected: settingsService.settings.languageOverride == 'hu',
settingsService.settings.languageOverride == 'hu',
onTap: () { onTap: () {
settingsService.setLanguageOverride('hu'); settingsService.setLanguageOverride('hu');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1549,8 +1527,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageJa, label: context.l10n.appSettings_languageJa,
value: 'ja', value: 'ja',
selected: selected: settingsService.settings.languageOverride == 'ja',
settingsService.settings.languageOverride == 'ja',
onTap: () { onTap: () {
settingsService.setLanguageOverride('ja'); settingsService.setLanguageOverride('ja');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1560,8 +1537,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_languageKo, label: context.l10n.appSettings_languageKo,
value: 'ko', value: 'ko',
selected: selected: settingsService.settings.languageOverride == 'ko',
settingsService.settings.languageOverride == 'ko',
onTap: () { onTap: () {
settingsService.setLanguageOverride('ko'); settingsService.setLanguageOverride('ko');
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1660,8 +1636,7 @@ class AppSettingsScreen extends StatelessWidget {
ctx, ctx,
label: context.l10n.appSettings_unitsMetric, label: context.l10n.appSettings_unitsMetric,
value: UnitSystem.metric, value: UnitSystem.metric,
selected: selected: settingsService.settings.unitSystem == UnitSystem.metric,
settingsService.settings.unitSystem == UnitSystem.metric,
onTap: () { onTap: () {
settingsService.setUnitSystem(UnitSystem.metric); settingsService.setUnitSystem(UnitSystem.metric);
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -1874,9 +1849,7 @@ class AppSettingsScreen extends StatelessWidget {
if (nameController.text.isEmpty) { if (nameController.text.isEmpty) {
showDismissibleSnackBar( showDismissibleSnackBar(
context, context,
content: Text( content: Text(context.l10n.settings_cyr2latProfileNameEmpty),
context.l10n.settings_cyr2latProfileNameEmpty,
),
); );
return; return;
} }
@@ -1964,9 +1937,7 @@ class AppSettingsScreen extends StatelessWidget {
if (nameController.text.isEmpty) { if (nameController.text.isEmpty) {
showDismissibleSnackBar( showDismissibleSnackBar(
context, context,
content: Text( content: Text(context.l10n.settings_cyr2latProfileNameEmpty),
context.l10n.settings_cyr2latProfileNameEmpty,
),
); );
return; return;
} }
+59 -45
View File
@@ -462,7 +462,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
color: MeshPalette.magenta, color: MeshPalette.magenta,
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all( border: Border.all(
color: Theme.of(context).colorScheme.surfaceContainerLow, color: Theme.of(
context,
).colorScheme.surfaceContainerLow,
width: 2, width: 2,
), ),
), ),
@@ -488,9 +490,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
Expanded( Expanded(
child: Text( child: Text(
channelLabel, channelLabel,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium
fontWeight: FontWeight.w500, ?.copyWith(fontWeight: FontWeight.w500),
),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -544,8 +545,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
], ],
if (unreadCount > 0) if (unreadCount > 0) UnreadBadge(count: unreadCount),
UnreadBadge(count: unreadCount),
], ],
), ),
], ],
@@ -806,12 +806,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
return MeshCard( return MeshCard(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
borderColor: isSelected && enabled borderColor: isSelected && enabled ? MeshPalette.blueLine : null,
? MeshPalette.blueLine color: isSelected && enabled ? MeshPalette.blueBg : null,
: null,
color: isSelected && enabled
? MeshPalette.blueBg
: null,
onTap: enabled onTap: enabled
? () { ? () {
setSheetState(() { setSheetState(() {
@@ -828,7 +824,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
name: title, name: title,
size: 38, size: 38,
color: enabled color: enabled
? (isSelected ? MeshPalette.blue : cardScheme.onSurfaceVariant) ? (isSelected
? MeshPalette.blue
: cardScheme.onSurfaceVariant)
: cardScheme.outline, : cardScheme.outline,
icon: icon, icon: icon,
), ),
@@ -840,17 +838,21 @@ class _ChannelsScreenState extends State<ChannelsScreen>
children: [ children: [
Text( Text(
title, title,
style: Theme.of(sheetContext).textTheme.bodyMedium?.copyWith( style: Theme.of(sheetContext).textTheme.bodyMedium
fontWeight: FontWeight.w500, ?.copyWith(
color: enabled ? null : cardScheme.outline, fontWeight: FontWeight.w500,
), color: enabled ? null : cardScheme.outline,
),
), ),
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
subtitle, subtitle,
style: Theme.of(sheetContext).textTheme.bodySmall?.copyWith( style: Theme.of(sheetContext).textTheme.bodySmall
color: enabled ? cardScheme.onSurfaceVariant : cardScheme.outline, ?.copyWith(
), color: enabled
? cardScheme.onSurfaceVariant
: cardScheme.outline,
),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -860,7 +862,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
if (enabled) if (enabled)
Icon( Icon(
Icons.chevron_right, Icons.chevron_right,
color: isSelected ? MeshPalette.blue : cardScheme.onSurfaceVariant, color: isSelected
? MeshPalette.blue
: cardScheme.onSurfaceVariant,
size: 20, size: 20,
), ),
], ],
@@ -998,9 +1002,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
showDismissibleSnackBar( showDismissibleSnackBar(
context, context,
content: Text( content: Text(
sheetContext sheetContext.l10n.channels_pskMustBe32Hex,
.l10n
.channels_pskMustBe32Hex,
), ),
); );
return; return;
@@ -1313,9 +1315,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
addPublicChannel = value ?? true; addPublicChannel = value ?? true;
}); });
}, },
title: Text( title: Text(sheetContext.l10n.community_addPublicChannel),
sheetContext.l10n.community_addPublicChannel,
),
subtitle: Text( subtitle: Text(
sheetContext.l10n.community_addPublicChannelHint, sheetContext.l10n.community_addPublicChannelHint,
), ),
@@ -1418,9 +1418,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
maxChildSize: 0.95, maxChildSize: 0.95,
builder: (_, scrollController) => Column( builder: (_, scrollController) => Column(
children: [ children: [
BottomSheetHeader( BottomSheetHeader(title: sheetContext.l10n.channels_addChannel),
title: sheetContext.l10n.channels_addChannel,
),
Expanded( Expanded(
child: ListView( child: ListView(
controller: scrollController, controller: scrollController,
@@ -1519,7 +1517,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
builder: (_, scrollController) => Column( builder: (_, scrollController) => Column(
children: [ children: [
BottomSheetHeader( BottomSheetHeader(
title: sheetContext.l10n.channels_editChannelTitle(channel.index), title: sheetContext.l10n.channels_editChannelTitle(
channel.index,
),
), ),
Expanded( Expanded(
child: ListView( child: ListView(
@@ -1569,7 +1569,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
), ),
SwitchListTile( SwitchListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
title: Text(sheetContext.l10n.channels_cyr2latCompression), title: Text(
sheetContext.l10n.channels_cyr2latCompression,
),
subtitle: Text( subtitle: Text(
sheetContext.l10n.channels_cyr2latCompressionDscr, sheetContext.l10n.channels_cyr2latCompressionDscr,
), ),
@@ -1592,14 +1594,14 @@ class _ChannelsScreenState extends State<ChannelsScreen>
.channels_cyr2latSettingsSubheading, .channels_cyr2latSettingsSubheading,
border: const OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
items: appSettingsService.settings.cyr2latProfiles.map(( items: appSettingsService.settings.cyr2latProfiles
profile, .map((profile) {
) { return DropdownMenuItem(
return DropdownMenuItem( value: profile.id,
value: profile.id, child: Text(profile.name),
child: Text(profile.name), );
); })
}).toList(), .toList(),
onChanged: (value) => setSheetState(() { onChanged: (value) => setSheetState(() {
selectedCyr2LatProfileId = value; selectedCyr2LatProfileId = value;
}), }),
@@ -1633,14 +1635,20 @@ class _ChannelsScreenState extends State<ChannelsScreen>
} on FormatException { } on FormatException {
showDismissibleSnackBar( showDismissibleSnackBar(
sheetContext, sheetContext,
content: Text(sheetContext.l10n.channels_pskMustBe32Hex), content: Text(
sheetContext.l10n.channels_pskMustBe32Hex,
),
); );
return; return;
} }
Navigator.pop(sheetContext); Navigator.pop(sheetContext);
try { try {
await connector.setChannel(channel.index, name, psk); await connector.setChannel(
channel.index,
name,
psk,
);
await connector.setChannelSmazEnabled( await connector.setChannelSmazEnabled(
channel.index, channel.index,
smazEnabled, smazEnabled,
@@ -1656,7 +1664,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
if (!context.mounted) return; if (!context.mounted) return;
showDismissibleSnackBar( showDismissibleSnackBar(
context, context,
content: Text(context.l10n.channels_channelUpdated(name)), content: Text(
context.l10n.channels_channelUpdated(name),
),
); );
} catch (e, st) { } catch (e, st) {
debugPrint(st.toString()); debugPrint(st.toString());
@@ -1732,7 +1742,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
}, },
child: Text( child: Text(
dialogContext.l10n.common_delete, dialogContext.l10n.common_delete,
style: TextStyle(color: Theme.of(dialogContext).colorScheme.error), style: TextStyle(
color: Theme.of(dialogContext).colorScheme.error,
),
), ),
), ),
], ],
@@ -1975,7 +1987,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
}, },
child: Text( child: Text(
dialogContext.l10n.community_delete, dialogContext.l10n.community_delete,
style: TextStyle(color: Theme.of(dialogContext).colorScheme.error), style: TextStyle(
color: Theme.of(dialogContext).colorScheme.error,
),
), ),
), ),
], ],
+130 -133
View File
@@ -109,10 +109,7 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
), ),
child: Text( child: Text(
context.l10n.community_scanInstructions, context.l10n.community_scanInstructions,
style: const TextStyle( style: const TextStyle(color: MeshPalette.ink2, fontSize: 13),
color: MeshPalette.ink2,
fontSize: 13,
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
@@ -185,61 +182,61 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
builder: (sheetContext) { builder: (sheetContext) {
final sheetScheme = Theme.of(sheetContext).colorScheme; final sheetScheme = Theme.of(sheetContext).colorScheme;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
BottomSheetHeader(title: context.l10n.community_alreadyMember), BottomSheetHeader(title: context.l10n.community_alreadyMember),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4), padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
child: Text( child: Text(
context.l10n.community_alreadyMemberMessage(community.name), context.l10n.community_alreadyMemberMessage(community.name),
style: TextStyle(color: sheetScheme.onSurfaceVariant), style: TextStyle(color: sheetScheme.onSurfaceVariant),
),
), ),
), MeshCard(
MeshCard( child: Row(
child: Row( children: [
children: [ const Icon(
const Icon( Icons.groups,
Icons.groups, color: MeshPalette.magenta,
color: MeshPalette.magenta, size: 32,
size: 32,
),
const SizedBox(width: 14),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
community.name,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
Text(
'ID: ${community.shortCommunityId}...',
style: MeshTheme.mono(
fontSize: 11.5,
color: sheetScheme.onSurfaceVariant,
),
),
],
), ),
), const SizedBox(width: 14),
], Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
community.name,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
Text(
'ID: ${community.shortCommunityId}...',
style: MeshTheme.mono(
fontSize: 11.5,
color: sheetScheme.onSurfaceVariant,
),
),
],
),
),
],
),
), ),
), Padding(
Padding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), child: FilledButton(
child: FilledButton( onPressed: () {
onPressed: () { Navigator.pop(sheetContext);
Navigator.pop(sheetContext); Navigator.pop(context);
Navigator.pop(context); },
}, child: Text(context.l10n.common_ok),
child: Text(context.l10n.common_ok), ),
), ),
), ],
],
); );
}, },
); );
@@ -258,90 +255,90 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
builder: (sheetContext, setSheetState) { builder: (sheetContext, setSheetState) {
final joinScheme = Theme.of(sheetContext).colorScheme; final joinScheme = Theme.of(sheetContext).colorScheme;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
BottomSheetHeader(title: context.l10n.community_joinTitle), BottomSheetHeader(title: context.l10n.community_joinTitle),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4), padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
child: Text( child: Text(
context.l10n.community_joinConfirmation(community.name), context.l10n.community_joinConfirmation(community.name),
style: TextStyle(color: joinScheme.onSurfaceVariant), style: TextStyle(color: joinScheme.onSurfaceVariant),
),
), ),
), MeshCard(
MeshCard( child: Row(
child: Row( children: [
children: [ AvatarCircle(
AvatarCircle( name: community.name,
name: community.name, icon: Icons.groups,
icon: Icons.groups, color: MeshPalette.magenta,
color: MeshPalette.magenta, size: 44,
size: 44, ),
), const SizedBox(width: 14),
const SizedBox(width: 14), Expanded(
Expanded( child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Text(
Text( community.name,
community.name, style: const TextStyle(
style: const TextStyle( fontWeight: FontWeight.w600,
fontWeight: FontWeight.w600, fontSize: 15,
fontSize: 15, ),
), ),
), Text(
Text( 'ID: ${community.shortCommunityId}...',
'ID: ${community.shortCommunityId}...', style: MeshTheme.mono(
style: MeshTheme.mono( fontSize: 11.5,
fontSize: 11.5, color: joinScheme.onSurfaceVariant,
color: joinScheme.onSurfaceVariant, ),
), ),
), ],
], ),
), ),
), ],
], ),
), ),
), CheckboxListTile(
CheckboxListTile( value: addPublicChannel,
value: addPublicChannel, onChanged: (value) {
onChanged: (value) { setSheetState(() {
setSheetState(() { addPublicChannel = value ?? true;
addPublicChannel = value ?? true; });
}); },
}, title: Text(context.l10n.community_addPublicChannel),
title: Text(context.l10n.community_addPublicChannel), subtitle: Text(context.l10n.community_addPublicChannelHint),
subtitle: Text(context.l10n.community_addPublicChannelHint), controlAffinity: ListTileControlAffinity.leading,
controlAffinity: ListTileControlAffinity.leading, contentPadding: const EdgeInsets.symmetric(horizontal: 16),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
child: Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () {
completer.complete(false);
Navigator.pop(sheetContext);
},
child: Text(context.l10n.common_cancel),
),
),
const SizedBox(width: 12),
Expanded(
child: FilledButton(
onPressed: () {
completer.complete(true);
Navigator.pop(sheetContext);
},
child: Text(context.l10n.community_join),
),
),
],
), ),
), Padding(
], padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
child: Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () {
completer.complete(false);
Navigator.pop(sheetContext);
},
child: Text(context.l10n.common_cancel),
),
),
const SizedBox(width: 12),
Expanded(
child: FilledButton(
onPressed: () {
completer.complete(true);
Navigator.pop(sheetContext);
},
child: Text(context.l10n.community_join),
),
),
],
),
),
],
); );
}, },
), ),
@@ -139,10 +139,7 @@ class _CompanionRadioStatsScreenState extends State<CompanionRadioStatsScreen> {
stats.lastSnrDb.toStringAsFixed(1), stats.lastSnrDb.toStringAsFixed(1),
), ),
Icons.signal_cellular_alt, Icons.signal_cellular_alt,
MeshTheme.snrColor( MeshTheme.snrColor(stats.lastSnrDb, blocked: false),
stats.lastSnrDb,
blocked: false,
),
), ),
], ],
), ),
+5 -2
View File
@@ -1574,7 +1574,8 @@ class _ContactTile extends StatelessWidget {
case advTypeSensor: case advTypeSensor:
return const Color(0xFF4ACCC4); // teal return const Color(0xFF4ACCC4); // teal
default: default:
return MeshPalette.blue; // chat — AvatarCircle handles deterministic hue return MeshPalette
.blue; // chat — AvatarCircle handles deterministic hue
} }
} }
@@ -1662,7 +1663,9 @@ class _ContactTile extends StatelessWidget {
Icon( Icon(
Icons.location_on, Icons.location_on,
size: 13, size: 13,
color: scheme.onSurfaceVariant.withValues(alpha: 0.55), color: scheme.onSurfaceVariant.withValues(
alpha: 0.55,
),
), ),
], ],
], ],
+1 -4
View File
@@ -351,10 +351,7 @@ class _NeighborsScreenState extends State<NeighborsScreen> {
for (var i = 0; i < _parsedNeighbors!.length; i++) for (var i = 0; i < _parsedNeighbors!.length; i++)
ListEntrance( ListEntrance(
index: i, index: i,
child: _buildNeighborRow( child: _buildNeighborRow(_parsedNeighbors![i], connector.currentSf),
_parsedNeighbors![i],
connector.currentSf,
),
), ),
], ],
); );
+5 -7
View File
@@ -801,9 +801,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen>
final selected = _selectedPath; final selected = _selectedPath;
return selected != null ? [selected] : const []; return selected != null ? [selected] : const [];
} }
return _displayPaths return _displayPaths.where((p) => !_hiddenPathIds.contains(p.id)).toList();
.where((p) => !_hiddenPathIds.contains(p.id))
.toList();
} }
/// Updates the playback path, but only when the selected path's geometry /// Updates the playback path, but only when the selected path's geometry
@@ -1249,7 +1247,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen>
final hex = hop.toRadixString(16).padLeft(2, '0').toUpperCase(); final hex = hop.toRadixString(16).padLeft(2, '0').toUpperCase();
showSharedNodeSheet( showSharedNodeSheet(
context, context,
title: '$hex: ${contact?.name ?? context.l10n.channelPath_unknownRepeater}', title:
'$hex: ${contact?.name ?? context.l10n.channelPath_unknownRepeater}',
paths: paths, paths: paths,
onSelect: _selectPath, onSelect: _selectPath,
); );
@@ -1539,9 +1538,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen>
tooltip: _panelCollapsed tooltip: _panelCollapsed
? l10n.pathMap_expandPanel ? l10n.pathMap_expandPanel
: l10n.pathMap_collapsePanel, : l10n.pathMap_collapsePanel,
onPressed: () => setState( onPressed: () =>
() => _panelCollapsed = !_panelCollapsed, setState(() => _panelCollapsed = !_panelCollapsed),
),
), ),
], ],
), ),
+547 -152
View File
@@ -470,26 +470,16 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon( const Icon(Icons.terminal, size: 48, color: MeshPalette.ink4),
Icons.terminal,
size: 48,
color: MeshPalette.ink4,
),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(
l10n.repeater_noCommandsSent, l10n.repeater_noCommandsSent,
style: MeshTheme.mono( style: MeshTheme.mono(fontSize: 13, color: MeshPalette.ink3),
fontSize: 13,
color: MeshPalette.ink3,
),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
l10n.repeater_typeCommandOrUseQuick, l10n.repeater_typeCommandOrUseQuick,
style: const TextStyle( style: const TextStyle(fontSize: 12, color: MeshPalette.ink4),
fontSize: 12,
color: MeshPalette.ink4,
),
), ),
], ],
), ),
@@ -518,9 +508,7 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
style: MeshTheme.mono( style: MeshTheme.mono(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: isCommand color: isCommand ? MeshPalette.blue : MeshPalette.ink3,
? MeshPalette.blue
: MeshPalette.ink3,
), ),
), ),
), ),
@@ -530,9 +518,7 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
entry['text']!, entry['text']!,
style: MeshTheme.mono( style: MeshTheme.mono(
fontSize: 12.5, fontSize: 12.5,
color: isCommand color: isCommand ? MeshPalette.blue : MeshPalette.ink,
? MeshPalette.blue
: MeshPalette.ink,
), ),
), ),
), ),
@@ -559,156 +545,522 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
void _showCommandHelp(BuildContext context) { void _showCommandHelp(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final generalCommands = [ final generalCommands = [
_CommandHelpEntry(command: 'advert', description: l10n.repeater_cliHelpAdvert), _CommandHelpEntry(
_CommandHelpEntry(command: 'reboot', description: l10n.repeater_cliHelpReboot), command: 'advert',
_CommandHelpEntry(command: 'clock', description: l10n.repeater_cliHelpClock), description: l10n.repeater_cliHelpAdvert,
_CommandHelpEntry(command: 'password {new-password}', description: l10n.repeater_cliHelpPassword), ),
_CommandHelpEntry(command: 'ver', description: l10n.repeater_cliHelpVersion), _CommandHelpEntry(
_CommandHelpEntry(command: 'clear stats', description: l10n.repeater_cliHelpClearStats), command: 'reboot',
_CommandHelpEntry(command: 'poweroff', description: l10n.repeater_cliHelpPowerOff), description: l10n.repeater_cliHelpReboot,
_CommandHelpEntry(command: 'shutdown', description: l10n.repeater_cliHelpPowerOff), ),
_CommandHelpEntry(command: 'clkreboot', description: l10n.repeater_cliHelpClkReboot), _CommandHelpEntry(
_CommandHelpEntry(command: 'advert.zerohop', description: l10n.repeater_cliHelpAdvertZeroHop), command: 'clock',
_CommandHelpEntry(command: 'start ota', description: l10n.repeater_cliHelpStartOta), description: l10n.repeater_cliHelpClock,
_CommandHelpEntry(command: 'time {epoch-seconds}', description: l10n.repeater_cliHelpTime), ),
_CommandHelpEntry(command: 'board', description: l10n.repeater_cliHelpBoard), _CommandHelpEntry(
_CommandHelpEntry(command: 'discover.neighbors', description: l10n.repeater_cliHelpDiscoverNeighbors), command: 'password {new-password}',
_CommandHelpEntry(command: 'powersaving', description: l10n.repeater_cliHelpPowersaving), description: l10n.repeater_cliHelpPassword,
_CommandHelpEntry(command: 'powersaving {on|off}', description: l10n.repeater_cliHelpPowersavingOnOff), ),
_CommandHelpEntry(command: 'erase', description: l10n.repeater_cliHelpErase), _CommandHelpEntry(
_CommandHelpEntry(command: 'stats-packets', description: l10n.repeater_cliHelpStatsPackets), command: 'ver',
_CommandHelpEntry(command: 'stats-radio', description: l10n.repeater_cliHelpStatsRadio), description: l10n.repeater_cliHelpVersion,
_CommandHelpEntry(command: 'stats-core', description: l10n.repeater_cliHelpStatsCore), ),
_CommandHelpEntry(
command: 'clear stats',
description: l10n.repeater_cliHelpClearStats,
),
_CommandHelpEntry(
command: 'poweroff',
description: l10n.repeater_cliHelpPowerOff,
),
_CommandHelpEntry(
command: 'shutdown',
description: l10n.repeater_cliHelpPowerOff,
),
_CommandHelpEntry(
command: 'clkreboot',
description: l10n.repeater_cliHelpClkReboot,
),
_CommandHelpEntry(
command: 'advert.zerohop',
description: l10n.repeater_cliHelpAdvertZeroHop,
),
_CommandHelpEntry(
command: 'start ota',
description: l10n.repeater_cliHelpStartOta,
),
_CommandHelpEntry(
command: 'time {epoch-seconds}',
description: l10n.repeater_cliHelpTime,
),
_CommandHelpEntry(
command: 'board',
description: l10n.repeater_cliHelpBoard,
),
_CommandHelpEntry(
command: 'discover.neighbors',
description: l10n.repeater_cliHelpDiscoverNeighbors,
),
_CommandHelpEntry(
command: 'powersaving',
description: l10n.repeater_cliHelpPowersaving,
),
_CommandHelpEntry(
command: 'powersaving {on|off}',
description: l10n.repeater_cliHelpPowersavingOnOff,
),
_CommandHelpEntry(
command: 'erase',
description: l10n.repeater_cliHelpErase,
),
_CommandHelpEntry(
command: 'stats-packets',
description: l10n.repeater_cliHelpStatsPackets,
),
_CommandHelpEntry(
command: 'stats-radio',
description: l10n.repeater_cliHelpStatsRadio,
),
_CommandHelpEntry(
command: 'stats-core',
description: l10n.repeater_cliHelpStatsCore,
),
]; ];
final settingsCommands = [ final settingsCommands = [
_CommandHelpEntry(command: 'set af {air-time-factor}', description: l10n.repeater_cliHelpSetAf), _CommandHelpEntry(
_CommandHelpEntry(command: 'set tx {tx-power-dbm}', description: l10n.repeater_cliHelpSetTx), command: 'set af {air-time-factor}',
_CommandHelpEntry(command: 'set repeat {on|off}', description: l10n.repeater_cliHelpSetRepeat), description: l10n.repeater_cliHelpSetAf,
_CommandHelpEntry(command: 'set allow.read.only {on|off}', description: l10n.repeater_cliHelpSetAllowReadOnly), ),
_CommandHelpEntry(command: 'set flood.max {max-hops}', description: l10n.repeater_cliHelpSetFloodMax), _CommandHelpEntry(
_CommandHelpEntry(command: 'set int.thresh {db}', description: l10n.repeater_cliHelpSetIntThresh), command: 'set tx {tx-power-dbm}',
_CommandHelpEntry(command: 'set agc.reset.interval {seconds}', description: l10n.repeater_cliHelpSetAgcResetInterval), description: l10n.repeater_cliHelpSetTx,
_CommandHelpEntry(command: 'set multi.acks {0|1}', description: l10n.repeater_cliHelpSetMultiAcks), ),
_CommandHelpEntry(command: 'set advert.interval {minutes}', description: l10n.repeater_cliHelpSetAdvertInterval), _CommandHelpEntry(
_CommandHelpEntry(command: 'set flood.advert.interval {hours}', description: l10n.repeater_cliHelpSetFloodAdvertInterval), command: 'set repeat {on|off}',
_CommandHelpEntry(command: 'set guest.password {guess-password}', description: l10n.repeater_cliHelpSetGuestPassword), description: l10n.repeater_cliHelpSetRepeat,
_CommandHelpEntry(command: 'set name {name}', description: l10n.repeater_cliHelpSetName), ),
_CommandHelpEntry(command: 'set lat {latitude}', description: l10n.repeater_cliHelpSetLat), _CommandHelpEntry(
_CommandHelpEntry(command: 'set lon {longitude}', description: l10n.repeater_cliHelpSetLon), command: 'set allow.read.only {on|off}',
_CommandHelpEntry(command: 'set radio {freq},{bw},{sf},{cr}', description: l10n.repeater_cliHelpSetRadio), description: l10n.repeater_cliHelpSetAllowReadOnly,
_CommandHelpEntry(command: 'set rxdelay {base}', description: l10n.repeater_cliHelpSetRxDelay), ),
_CommandHelpEntry(command: 'set txdelay {factor}', description: l10n.repeater_cliHelpSetTxDelay), _CommandHelpEntry(
_CommandHelpEntry(command: 'set direct.txdelay {factor}', description: l10n.repeater_cliHelpSetDirectTxDelay), command: 'set flood.max {max-hops}',
_CommandHelpEntry(command: 'set bridge.enabled {on|off}', description: l10n.repeater_cliHelpSetBridgeEnabled), description: l10n.repeater_cliHelpSetFloodMax,
_CommandHelpEntry(command: 'set bridge.delay {0-10000}', description: l10n.repeater_cliHelpSetBridgeDelay), ),
_CommandHelpEntry(command: 'set bridge.source {rx|tx}', description: l10n.repeater_cliHelpSetBridgeSource), _CommandHelpEntry(
_CommandHelpEntry(command: 'set bridge.baud {speed}', description: l10n.repeater_cliHelpSetBridgeBaud), command: 'set int.thresh {db}',
_CommandHelpEntry(command: 'set bridge.secret {shared-secret}', description: l10n.repeater_cliHelpSetBridgeSecret), description: l10n.repeater_cliHelpSetIntThresh,
_CommandHelpEntry(command: 'set adc.multiplier {factor}', description: l10n.repeater_cliHelpSetAdcMultiplier), ),
_CommandHelpEntry(command: 'tempradio {freq},{bw},{sf},{cr},{minutes}', description: l10n.repeater_cliHelpTempRadio), _CommandHelpEntry(
_CommandHelpEntry(command: 'setperm {pubkey-hex} {permissions}', description: l10n.repeater_cliHelpSetPerm), command: 'set agc.reset.interval {seconds}',
_CommandHelpEntry(command: 'set dutycycle {1-100}', description: l10n.repeater_cliHelpSetDutyCycle), description: l10n.repeater_cliHelpSetAgcResetInterval,
_CommandHelpEntry(command: 'set prv.key {hex}', description: l10n.repeater_cliHelpSetPrvKey), ),
_CommandHelpEntry(command: 'set radio.rxgain {on|off}', description: l10n.repeater_cliHelpSetRadioRxGain), _CommandHelpEntry(
_CommandHelpEntry(command: 'set owner.info {text}', description: l10n.repeater_cliHelpSetOwnerInfo), command: 'set multi.acks {0|1}',
_CommandHelpEntry(command: 'set path.hash.mode {0|1|2}', description: l10n.repeater_cliHelpSetPathHashMode), description: l10n.repeater_cliHelpSetMultiAcks,
_CommandHelpEntry(command: 'set loop.detect {off|minimal|moderate|strict}', description: l10n.repeater_cliHelpSetLoopDetect), ),
_CommandHelpEntry(command: 'set freq {mhz}', description: l10n.repeater_cliHelpSetFreq), _CommandHelpEntry(
_CommandHelpEntry(command: 'set bridge.channel {1-14}', description: l10n.repeater_cliHelpSetBridgeChannel), command: 'set advert.interval {minutes}',
description: l10n.repeater_cliHelpSetAdvertInterval,
),
_CommandHelpEntry(
command: 'set flood.advert.interval {hours}',
description: l10n.repeater_cliHelpSetFloodAdvertInterval,
),
_CommandHelpEntry(
command: 'set guest.password {guess-password}',
description: l10n.repeater_cliHelpSetGuestPassword,
),
_CommandHelpEntry(
command: 'set name {name}',
description: l10n.repeater_cliHelpSetName,
),
_CommandHelpEntry(
command: 'set lat {latitude}',
description: l10n.repeater_cliHelpSetLat,
),
_CommandHelpEntry(
command: 'set lon {longitude}',
description: l10n.repeater_cliHelpSetLon,
),
_CommandHelpEntry(
command: 'set radio {freq},{bw},{sf},{cr}',
description: l10n.repeater_cliHelpSetRadio,
),
_CommandHelpEntry(
command: 'set rxdelay {base}',
description: l10n.repeater_cliHelpSetRxDelay,
),
_CommandHelpEntry(
command: 'set txdelay {factor}',
description: l10n.repeater_cliHelpSetTxDelay,
),
_CommandHelpEntry(
command: 'set direct.txdelay {factor}',
description: l10n.repeater_cliHelpSetDirectTxDelay,
),
_CommandHelpEntry(
command: 'set bridge.enabled {on|off}',
description: l10n.repeater_cliHelpSetBridgeEnabled,
),
_CommandHelpEntry(
command: 'set bridge.delay {0-10000}',
description: l10n.repeater_cliHelpSetBridgeDelay,
),
_CommandHelpEntry(
command: 'set bridge.source {rx|tx}',
description: l10n.repeater_cliHelpSetBridgeSource,
),
_CommandHelpEntry(
command: 'set bridge.baud {speed}',
description: l10n.repeater_cliHelpSetBridgeBaud,
),
_CommandHelpEntry(
command: 'set bridge.secret {shared-secret}',
description: l10n.repeater_cliHelpSetBridgeSecret,
),
_CommandHelpEntry(
command: 'set adc.multiplier {factor}',
description: l10n.repeater_cliHelpSetAdcMultiplier,
),
_CommandHelpEntry(
command: 'tempradio {freq},{bw},{sf},{cr},{minutes}',
description: l10n.repeater_cliHelpTempRadio,
),
_CommandHelpEntry(
command: 'setperm {pubkey-hex} {permissions}',
description: l10n.repeater_cliHelpSetPerm,
),
_CommandHelpEntry(
command: 'set dutycycle {1-100}',
description: l10n.repeater_cliHelpSetDutyCycle,
),
_CommandHelpEntry(
command: 'set prv.key {hex}',
description: l10n.repeater_cliHelpSetPrvKey,
),
_CommandHelpEntry(
command: 'set radio.rxgain {on|off}',
description: l10n.repeater_cliHelpSetRadioRxGain,
),
_CommandHelpEntry(
command: 'set owner.info {text}',
description: l10n.repeater_cliHelpSetOwnerInfo,
),
_CommandHelpEntry(
command: 'set path.hash.mode {0|1|2}',
description: l10n.repeater_cliHelpSetPathHashMode,
),
_CommandHelpEntry(
command: 'set loop.detect {off|minimal|moderate|strict}',
description: l10n.repeater_cliHelpSetLoopDetect,
),
_CommandHelpEntry(
command: 'set freq {mhz}',
description: l10n.repeater_cliHelpSetFreq,
),
_CommandHelpEntry(
command: 'set bridge.channel {1-14}',
description: l10n.repeater_cliHelpSetBridgeChannel,
),
]; ];
final bridgeCommands = [ final bridgeCommands = [
_CommandHelpEntry(command: 'get bridge.type', description: l10n.repeater_cliHelpGetBridgeType), _CommandHelpEntry(
command: 'get bridge.type',
description: l10n.repeater_cliHelpGetBridgeType,
),
]; ];
final loggingCommands = [ final loggingCommands = [
_CommandHelpEntry(command: 'log start', description: l10n.repeater_cliHelpLogStart), _CommandHelpEntry(
_CommandHelpEntry(command: 'log stop', description: l10n.repeater_cliHelpLogStop), command: 'log start',
_CommandHelpEntry(command: 'log erase', description: l10n.repeater_cliHelpLogErase), description: l10n.repeater_cliHelpLogStart,
),
_CommandHelpEntry(
command: 'log stop',
description: l10n.repeater_cliHelpLogStop,
),
_CommandHelpEntry(
command: 'log erase',
description: l10n.repeater_cliHelpLogErase,
),
]; ];
final neighborCommands = [ final neighborCommands = [
_CommandHelpEntry(command: 'neighbors', description: l10n.repeater_cliHelpNeighbors), _CommandHelpEntry(
_CommandHelpEntry(command: 'neighbor.remove {pubkey-prefix}', description: l10n.repeater_cliHelpNeighborRemove), command: 'neighbors',
description: l10n.repeater_cliHelpNeighbors,
),
_CommandHelpEntry(
command: 'neighbor.remove {pubkey-prefix}',
description: l10n.repeater_cliHelpNeighborRemove,
),
]; ];
final regionCommands = [ final regionCommands = [
_CommandHelpEntry(command: 'region', description: l10n.repeater_cliHelpRegion), _CommandHelpEntry(
_CommandHelpEntry(command: 'region load', description: l10n.repeater_cliHelpRegionLoad), command: 'region',
_CommandHelpEntry(command: 'region get {* | name-prefix}', description: l10n.repeater_cliHelpRegionGet), description: l10n.repeater_cliHelpRegion,
_CommandHelpEntry(command: 'region put {name} {* | parent-name-prefix}', description: l10n.repeater_cliHelpRegionPut), ),
_CommandHelpEntry(command: 'region remove {name}', description: l10n.repeater_cliHelpRegionRemove), _CommandHelpEntry(
_CommandHelpEntry(command: 'region allowf {* | name-prefix}', description: l10n.repeater_cliHelpRegionAllowf), command: 'region load',
_CommandHelpEntry(command: 'region denyf {* | name-prefix}', description: l10n.repeater_cliHelpRegionDenyf), description: l10n.repeater_cliHelpRegionLoad,
_CommandHelpEntry(command: 'region home', description: l10n.repeater_cliHelpRegionHome), ),
_CommandHelpEntry(command: 'region home {* | name-prefix}', description: l10n.repeater_cliHelpRegionHomeSet), _CommandHelpEntry(
_CommandHelpEntry(command: 'region save', description: l10n.repeater_cliHelpRegionSave), command: 'region get {* | name-prefix}',
_CommandHelpEntry(command: 'region default', description: l10n.repeater_cliHelpRegionDefault), description: l10n.repeater_cliHelpRegionGet,
_CommandHelpEntry(command: 'region default {* | name-prefix | <null>}', description: l10n.repeater_cliHelpRegionDefaultSet), ),
_CommandHelpEntry(command: 'region list allowed', description: l10n.repeater_cliHelpRegionListAllowed), _CommandHelpEntry(
_CommandHelpEntry(command: 'region list denied', description: l10n.repeater_cliHelpRegionListDenied), command: 'region put {name} {* | parent-name-prefix}',
description: l10n.repeater_cliHelpRegionPut,
),
_CommandHelpEntry(
command: 'region remove {name}',
description: l10n.repeater_cliHelpRegionRemove,
),
_CommandHelpEntry(
command: 'region allowf {* | name-prefix}',
description: l10n.repeater_cliHelpRegionAllowf,
),
_CommandHelpEntry(
command: 'region denyf {* | name-prefix}',
description: l10n.repeater_cliHelpRegionDenyf,
),
_CommandHelpEntry(
command: 'region home',
description: l10n.repeater_cliHelpRegionHome,
),
_CommandHelpEntry(
command: 'region home {* | name-prefix}',
description: l10n.repeater_cliHelpRegionHomeSet,
),
_CommandHelpEntry(
command: 'region save',
description: l10n.repeater_cliHelpRegionSave,
),
_CommandHelpEntry(
command: 'region default',
description: l10n.repeater_cliHelpRegionDefault,
),
_CommandHelpEntry(
command: 'region default {* | name-prefix | <null>}',
description: l10n.repeater_cliHelpRegionDefaultSet,
),
_CommandHelpEntry(
command: 'region list allowed',
description: l10n.repeater_cliHelpRegionListAllowed,
),
_CommandHelpEntry(
command: 'region list denied',
description: l10n.repeater_cliHelpRegionListDenied,
),
]; ];
final getCommands = [ final getCommands = [
_CommandHelpEntry(command: 'get name', description: l10n.repeater_cliHelpGetName), _CommandHelpEntry(
_CommandHelpEntry(command: 'get role', description: l10n.repeater_cliHelpGetRole), command: 'get name',
_CommandHelpEntry(command: 'get public.key', description: l10n.repeater_cliHelpGetPublicKey), description: l10n.repeater_cliHelpGetName,
_CommandHelpEntry(command: 'get prv.key', description: l10n.repeater_cliHelpGetPrvKey), ),
_CommandHelpEntry(command: 'get repeat', description: l10n.repeater_cliHelpGetRepeat), _CommandHelpEntry(
_CommandHelpEntry(command: 'get tx', description: l10n.repeater_cliHelpGetTx), command: 'get role',
_CommandHelpEntry(command: 'get freq', description: l10n.repeater_cliHelpGetFreq), description: l10n.repeater_cliHelpGetRole,
_CommandHelpEntry(command: 'get radio', description: l10n.repeater_cliHelpGetRadio), ),
_CommandHelpEntry(command: 'get radio.rxgain', description: l10n.repeater_cliHelpGetRadioRxGain), _CommandHelpEntry(
_CommandHelpEntry(command: 'get af', description: l10n.repeater_cliHelpGetAf), command: 'get public.key',
_CommandHelpEntry(command: 'get dutycycle', description: l10n.repeater_cliHelpGetDutyCycle), description: l10n.repeater_cliHelpGetPublicKey,
_CommandHelpEntry(command: 'get int.thresh', description: l10n.repeater_cliHelpGetIntThresh), ),
_CommandHelpEntry(command: 'get agc.reset.interval', description: l10n.repeater_cliHelpGetAgcResetInterval), _CommandHelpEntry(
_CommandHelpEntry(command: 'get multi.acks', description: l10n.repeater_cliHelpGetMultiAcks), command: 'get prv.key',
_CommandHelpEntry(command: 'get allow.read.only', description: l10n.repeater_cliHelpGetAllowReadOnly), description: l10n.repeater_cliHelpGetPrvKey,
_CommandHelpEntry(command: 'get advert.interval', description: l10n.repeater_cliHelpGetAdvertInterval), ),
_CommandHelpEntry(command: 'get flood.advert.interval', description: l10n.repeater_cliHelpGetFloodAdvertInterval), _CommandHelpEntry(
_CommandHelpEntry(command: 'get guest.password', description: l10n.repeater_cliHelpGetGuestPassword), command: 'get repeat',
_CommandHelpEntry(command: 'get lat', description: l10n.repeater_cliHelpGetLat), description: l10n.repeater_cliHelpGetRepeat,
_CommandHelpEntry(command: 'get lon', description: l10n.repeater_cliHelpGetLon), ),
_CommandHelpEntry(command: 'get rxdelay', description: l10n.repeater_cliHelpGetRxDelay), _CommandHelpEntry(
_CommandHelpEntry(command: 'get txdelay', description: l10n.repeater_cliHelpGetTxDelay), command: 'get tx',
_CommandHelpEntry(command: 'get direct.txdelay', description: l10n.repeater_cliHelpGetDirectTxDelay), description: l10n.repeater_cliHelpGetTx,
_CommandHelpEntry(command: 'get flood.max', description: l10n.repeater_cliHelpGetFloodMax), ),
_CommandHelpEntry(command: 'get owner.info', description: l10n.repeater_cliHelpGetOwnerInfo), _CommandHelpEntry(
_CommandHelpEntry(command: 'get path.hash.mode', description: l10n.repeater_cliHelpGetPathHashMode), command: 'get freq',
_CommandHelpEntry(command: 'get loop.detect', description: l10n.repeater_cliHelpGetLoopDetect), description: l10n.repeater_cliHelpGetFreq,
_CommandHelpEntry(command: 'get acl', description: l10n.repeater_cliHelpGetAcl), ),
_CommandHelpEntry(command: 'get bridge.enabled', description: l10n.repeater_cliHelpGetBridgeEnabled), _CommandHelpEntry(
_CommandHelpEntry(command: 'get bridge.delay', description: l10n.repeater_cliHelpGetBridgeDelay), command: 'get radio',
_CommandHelpEntry(command: 'get bridge.source', description: l10n.repeater_cliHelpGetBridgeSource), description: l10n.repeater_cliHelpGetRadio,
_CommandHelpEntry(command: 'get bridge.baud', description: l10n.repeater_cliHelpGetBridgeBaud), ),
_CommandHelpEntry(command: 'get bridge.channel', description: l10n.repeater_cliHelpGetBridgeChannel), _CommandHelpEntry(
_CommandHelpEntry(command: 'get bridge.secret', description: l10n.repeater_cliHelpGetBridgeSecret), command: 'get radio.rxgain',
_CommandHelpEntry(command: 'get bootloader.ver', description: l10n.repeater_cliHelpGetBootloaderVer), description: l10n.repeater_cliHelpGetRadioRxGain,
_CommandHelpEntry(command: 'get adc.multiplier', description: l10n.repeater_cliHelpGetAdcMultiplier), ),
_CommandHelpEntry(
command: 'get af',
description: l10n.repeater_cliHelpGetAf,
),
_CommandHelpEntry(
command: 'get dutycycle',
description: l10n.repeater_cliHelpGetDutyCycle,
),
_CommandHelpEntry(
command: 'get int.thresh',
description: l10n.repeater_cliHelpGetIntThresh,
),
_CommandHelpEntry(
command: 'get agc.reset.interval',
description: l10n.repeater_cliHelpGetAgcResetInterval,
),
_CommandHelpEntry(
command: 'get multi.acks',
description: l10n.repeater_cliHelpGetMultiAcks,
),
_CommandHelpEntry(
command: 'get allow.read.only',
description: l10n.repeater_cliHelpGetAllowReadOnly,
),
_CommandHelpEntry(
command: 'get advert.interval',
description: l10n.repeater_cliHelpGetAdvertInterval,
),
_CommandHelpEntry(
command: 'get flood.advert.interval',
description: l10n.repeater_cliHelpGetFloodAdvertInterval,
),
_CommandHelpEntry(
command: 'get guest.password',
description: l10n.repeater_cliHelpGetGuestPassword,
),
_CommandHelpEntry(
command: 'get lat',
description: l10n.repeater_cliHelpGetLat,
),
_CommandHelpEntry(
command: 'get lon',
description: l10n.repeater_cliHelpGetLon,
),
_CommandHelpEntry(
command: 'get rxdelay',
description: l10n.repeater_cliHelpGetRxDelay,
),
_CommandHelpEntry(
command: 'get txdelay',
description: l10n.repeater_cliHelpGetTxDelay,
),
_CommandHelpEntry(
command: 'get direct.txdelay',
description: l10n.repeater_cliHelpGetDirectTxDelay,
),
_CommandHelpEntry(
command: 'get flood.max',
description: l10n.repeater_cliHelpGetFloodMax,
),
_CommandHelpEntry(
command: 'get owner.info',
description: l10n.repeater_cliHelpGetOwnerInfo,
),
_CommandHelpEntry(
command: 'get path.hash.mode',
description: l10n.repeater_cliHelpGetPathHashMode,
),
_CommandHelpEntry(
command: 'get loop.detect',
description: l10n.repeater_cliHelpGetLoopDetect,
),
_CommandHelpEntry(
command: 'get acl',
description: l10n.repeater_cliHelpGetAcl,
),
_CommandHelpEntry(
command: 'get bridge.enabled',
description: l10n.repeater_cliHelpGetBridgeEnabled,
),
_CommandHelpEntry(
command: 'get bridge.delay',
description: l10n.repeater_cliHelpGetBridgeDelay,
),
_CommandHelpEntry(
command: 'get bridge.source',
description: l10n.repeater_cliHelpGetBridgeSource,
),
_CommandHelpEntry(
command: 'get bridge.baud',
description: l10n.repeater_cliHelpGetBridgeBaud,
),
_CommandHelpEntry(
command: 'get bridge.channel',
description: l10n.repeater_cliHelpGetBridgeChannel,
),
_CommandHelpEntry(
command: 'get bridge.secret',
description: l10n.repeater_cliHelpGetBridgeSecret,
),
_CommandHelpEntry(
command: 'get bootloader.ver',
description: l10n.repeater_cliHelpGetBootloaderVer,
),
_CommandHelpEntry(
command: 'get adc.multiplier',
description: l10n.repeater_cliHelpGetAdcMultiplier,
),
]; ];
final powerMgmtCommands = [ final powerMgmtCommands = [
_CommandHelpEntry(command: 'get pwrmgt.support', description: l10n.repeater_cliHelpGetPwrMgtSupport), _CommandHelpEntry(
_CommandHelpEntry(command: 'get pwrmgt.source', description: l10n.repeater_cliHelpGetPwrMgtSource), command: 'get pwrmgt.support',
_CommandHelpEntry(command: 'get pwrmgt.bootreason', description: l10n.repeater_cliHelpGetPwrMgtBootReason), description: l10n.repeater_cliHelpGetPwrMgtSupport,
_CommandHelpEntry(command: 'get pwrmgt.bootmv', description: l10n.repeater_cliHelpGetPwrMgtBootMv), ),
_CommandHelpEntry(
command: 'get pwrmgt.source',
description: l10n.repeater_cliHelpGetPwrMgtSource,
),
_CommandHelpEntry(
command: 'get pwrmgt.bootreason',
description: l10n.repeater_cliHelpGetPwrMgtBootReason,
),
_CommandHelpEntry(
command: 'get pwrmgt.bootmv',
description: l10n.repeater_cliHelpGetPwrMgtBootMv,
),
]; ];
final sensorCommands = [ final sensorCommands = [
_CommandHelpEntry(command: 'sensor get {key}', description: l10n.repeater_cliHelpSensorGet), _CommandHelpEntry(
_CommandHelpEntry(command: 'sensor set {key} {value}', description: l10n.repeater_cliHelpSensorSet), command: 'sensor get {key}',
_CommandHelpEntry(command: 'sensor list [start]', description: l10n.repeater_cliHelpSensorList), description: l10n.repeater_cliHelpSensorGet,
),
_CommandHelpEntry(
command: 'sensor set {key} {value}',
description: l10n.repeater_cliHelpSensorSet,
),
_CommandHelpEntry(
command: 'sensor list [start]',
description: l10n.repeater_cliHelpSensorList,
),
]; ];
final gpsCommands = [ final gpsCommands = [
_CommandHelpEntry(command: 'gps', description: l10n.repeater_cliHelpGps), _CommandHelpEntry(command: 'gps', description: l10n.repeater_cliHelpGps),
_CommandHelpEntry(command: 'gps {on|off}', description: l10n.repeater_cliHelpGpsOnOff), _CommandHelpEntry(
_CommandHelpEntry(command: 'gps sync', description: l10n.repeater_cliHelpGpsSync), command: 'gps {on|off}',
_CommandHelpEntry(command: 'gps setloc', description: l10n.repeater_cliHelpGpsSetLoc), description: l10n.repeater_cliHelpGpsOnOff,
_CommandHelpEntry(command: 'gps advert', description: l10n.repeater_cliHelpGpsAdvert), ),
_CommandHelpEntry(command: 'gps advert {none|share|prefs}', description: l10n.repeater_cliHelpGpsAdvertSet), _CommandHelpEntry(
command: 'gps sync',
description: l10n.repeater_cliHelpGpsSync,
),
_CommandHelpEntry(
command: 'gps setloc',
description: l10n.repeater_cliHelpGpsSetLoc,
),
_CommandHelpEntry(
command: 'gps advert',
description: l10n.repeater_cliHelpGpsAdvert,
),
_CommandHelpEntry(
command: 'gps advert {none|share|prefs}',
description: l10n.repeater_cliHelpGpsAdvertSet,
),
]; ];
showDialog( showDialog(
@@ -720,27 +1072,64 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(l10n.repeater_commandsListNote, style: const TextStyle(fontSize: 13)), Text(
l10n.repeater_commandsListNote,
style: const TextStyle(fontSize: 13),
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_general, generalCommands), _buildHelpSection(
context,
l10n.repeater_general,
generalCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_getCategory, getCommands), _buildHelpSection(
context,
l10n.repeater_getCategory,
getCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_settingsCategory, settingsCommands), _buildHelpSection(
context,
l10n.repeater_settingsCategory,
settingsCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_powerMgmt, powerMgmtCommands), _buildHelpSection(
context,
l10n.repeater_powerMgmt,
powerMgmtCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_sensors, sensorCommands), _buildHelpSection(context, l10n.repeater_sensors, sensorCommands),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_bridge, bridgeCommands), _buildHelpSection(context, l10n.repeater_bridge, bridgeCommands),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_logging, loggingCommands), _buildHelpSection(
context,
l10n.repeater_logging,
loggingCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_neighborsRepeaterOnly, neighborCommands), _buildHelpSection(
context,
l10n.repeater_neighborsRepeaterOnly,
neighborCommands,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_regionManagementRepeaterOnly, regionCommands, note: l10n.repeater_regionNote), _buildHelpSection(
context,
l10n.repeater_regionManagementRepeaterOnly,
regionCommands,
note: l10n.repeater_regionNote,
),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildHelpSection(context, l10n.repeater_gpsManagement, gpsCommands, note: l10n.repeater_gpsNote), _buildHelpSection(
context,
l10n.repeater_gpsManagement,
gpsCommands,
note: l10n.repeater_gpsNote,
),
], ],
), ),
), ),
@@ -764,10 +1153,16 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)), Text(
title,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
if (note != null) ...[ if (note != null) ...[
const SizedBox(height: 4), const SizedBox(height: 4),
Text(note, style: TextStyle(fontSize: 11, color: scheme.onSurfaceVariant)), Text(
note,
style: TextStyle(fontSize: 11, color: scheme.onSurfaceVariant),
),
], ],
const SizedBox(height: 8), const SizedBox(height: 8),
...commands.map((entry) => _buildHelpCommandCard(context, entry)), ...commands.map((entry) => _buildHelpCommandCard(context, entry)),
+10 -16
View File
@@ -70,9 +70,7 @@ class RepeaterHubScreen extends StatelessWidget {
children: [ children: [
Text( Text(
repeater.name, repeater.name,
style: Theme.of(context) style: Theme.of(context).textTheme.titleMedium
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.w700), ?.copyWith(fontWeight: FontWeight.w700),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@@ -88,9 +86,7 @@ class RepeaterHubScreen extends StatelessWidget {
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
repeater.pathLabel(l10n), repeater.pathLabel(l10n),
style: Theme.of(context) style: Theme.of(context).textTheme.bodySmall
.textTheme
.bodySmall
?.copyWith(color: scheme.onSurfaceVariant), ?.copyWith(color: scheme.onSurfaceVariant),
), ),
if (repeater.hasLocation) ...[ if (repeater.hasLocation) ...[
@@ -122,7 +118,9 @@ class RepeaterHubScreen extends StatelessWidget {
), ),
StatusChip( StatusChip(
label: isAdmin ? 'ADMIN' : 'GUEST', label: isAdmin ? 'ADMIN' : 'GUEST',
color: isAdmin ? MeshPalette.blue : scheme.onSurfaceVariant, color: isAdmin
? MeshPalette.blue
: scheme.onSurfaceVariant,
), ),
], ],
), ),
@@ -169,7 +167,9 @@ class RepeaterHubScreen extends StatelessWidget {
// Tools // Tools
SectionHeader( SectionHeader(
isAdmin ? l10n.repeater_managementTools : l10n.repeater_guestTools, isAdmin
? l10n.repeater_managementTools
: l10n.repeater_guestTools,
), ),
_HubActionTile( _HubActionTile(
@@ -306,9 +306,7 @@ class _HubActionTile extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: accentColor.withValues(alpha: 0.12), color: accentColor.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(MeshRadii.md), borderRadius: BorderRadius.circular(MeshRadii.md),
border: Border.all( border: Border.all(color: accentColor.withValues(alpha: 0.3)),
color: accentColor.withValues(alpha: 0.3),
),
), ),
alignment: Alignment.center, alignment: Alignment.center,
child: Icon(icon, size: 22, color: accentColor), child: Icon(icon, size: 22, color: accentColor),
@@ -336,11 +334,7 @@ class _HubActionTile extends StatelessWidget {
], ],
), ),
), ),
Icon( Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 20),
Icons.chevron_right,
color: scheme.onSurfaceVariant,
size: 20,
),
], ],
), ),
), ),
+10 -15
View File
@@ -1196,9 +1196,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
const SizedBox(height: 12), const SizedBox(height: 12),
DropdownButtonFormField<int>( DropdownButtonFormField<int>(
initialValue: _bandwidth, initialValue: _bandwidth,
decoration: InputDecoration( decoration: InputDecoration(labelText: l10n.repeater_bandwidth),
labelText: l10n.repeater_bandwidth,
),
items: _bandwidthOptions.map((bw) { items: _bandwidthOptions.map((bw) {
return DropdownMenuItem( return DropdownMenuItem(
value: bw, value: bw,
@@ -1478,7 +1476,9 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
child: ListTile( child: ListTile(
title: Text(l10n.repeater_localAdvertInterval), title: Text(l10n.repeater_localAdvertInterval),
subtitle: Text( subtitle: Text(
l10n.repeater_localAdvertIntervalMinutes(_advertInterval), l10n.repeater_localAdvertIntervalMinutes(
_advertInterval,
),
), ),
trailing: Switch( trailing: Switch(
value: _advertEnable, value: _advertEnable,
@@ -1516,7 +1516,9 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
min: 60, min: 60,
max: 240, max: 240,
divisions: 18, divisions: 18,
label: l10n.repeater_localAdvertIntervalMinutes(_advertInterval), label: l10n.repeater_localAdvertIntervalMinutes(
_advertInterval,
),
onChanged: _advertEnable onChanged: _advertEnable
? (value) { ? (value) {
setState(() { setState(() {
@@ -2014,9 +2016,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
), ),
subtitle: Text( subtitle: Text(
l10n.repeater_rebootRepeaterSubtitle, l10n.repeater_rebootRepeaterSubtitle,
style: const TextStyle( style: const TextStyle(color: MeshPalette.warnDim),
color: MeshPalette.warnDim,
),
), ),
onTap: () => _confirmAction( onTap: () => _confirmAction(
l10n.repeater_rebootRepeater, l10n.repeater_rebootRepeater,
@@ -2027,19 +2027,14 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
), ),
// Regenerate identity key - hidden until fully implemented // Regenerate identity key - hidden until fully implemented
ListTile( ListTile(
leading: const Icon( leading: const Icon(Icons.delete_forever, color: MeshPalette.alert),
Icons.delete_forever,
color: MeshPalette.alert,
),
title: Text( title: Text(
l10n.repeater_eraseFileSystem, l10n.repeater_eraseFileSystem,
style: const TextStyle(color: MeshPalette.alert), style: const TextStyle(color: MeshPalette.alert),
), ),
subtitle: Text( subtitle: Text(
l10n.repeater_eraseFileSystemSubtitle, l10n.repeater_eraseFileSystemSubtitle,
style: const TextStyle( style: const TextStyle(color: MeshPalette.warnDim),
color: MeshPalette.warnDim,
),
), ),
onTap: () => _confirmAction( onTap: () => _confirmAction(
l10n.repeater_eraseFileSystem, l10n.repeater_eraseFileSystem,
+10 -7
View File
@@ -605,7 +605,8 @@ class _RepeaterStatusScreenState extends State<RepeaterStatusScreen> {
final batteryMv = final batteryMv =
connector.getRepeaterBatteryMillivolts(widget.repeater.publicKeyHex) ?? connector.getRepeaterBatteryMillivolts(widget.repeater.publicKeyHex) ??
_batteryMv; _batteryMv;
if (batteryMv == null) return Theme.of(context).colorScheme.onSurfaceVariant; if (batteryMv == null)
return Theme.of(context).colorScheme.onSurfaceVariant;
final percent = estimateBatteryPercentFromMillivolts( final percent = estimateBatteryPercentFromMillivolts(
batteryMv, batteryMv,
_batteryChemistry(), _batteryChemistry(),
@@ -624,12 +625,14 @@ class _RepeaterStatusScreenState extends State<RepeaterStatusScreen> {
crossAxisSpacing: 8, crossAxisSpacing: 8,
childAspectRatio: 2.2, childAspectRatio: 2.2,
children: items children: items
.map((item) => StatTile( .map(
icon: item.icon, (item) => StatTile(
label: item.label, icon: item.icon,
value: item.value, label: item.label,
color: item.color, value: item.value,
)) color: item.color,
),
)
.toList(), .toList(),
); );
} }
+21 -25
View File
@@ -482,30 +482,30 @@ class _ConnectionStatusHeader extends StatelessWidget {
final (String label, Color color, bool pulse) = switch (connector.state) { final (String label, Color color, bool pulse) = switch (connector.state) {
MeshCoreConnectionState.scanning => ( MeshCoreConnectionState.scanning => (
l10n.scanner_scanning, l10n.scanner_scanning,
MeshPalette.blue, MeshPalette.blue,
true, true,
), ),
MeshCoreConnectionState.connecting => ( MeshCoreConnectionState.connecting => (
l10n.scanner_connecting, l10n.scanner_connecting,
MeshPalette.warn, MeshPalette.warn,
true, true,
), ),
MeshCoreConnectionState.connected => ( MeshCoreConnectionState.connected => (
l10n.scanner_connectedTo(connector.deviceDisplayName), l10n.scanner_connectedTo(connector.deviceDisplayName),
MeshPalette.signal, MeshPalette.signal,
false, false,
), ),
MeshCoreConnectionState.disconnecting => ( MeshCoreConnectionState.disconnecting => (
l10n.scanner_disconnecting, l10n.scanner_disconnecting,
MeshPalette.warn, MeshPalette.warn,
true, true,
), ),
MeshCoreConnectionState.disconnected => ( MeshCoreConnectionState.disconnected => (
l10n.scanner_notConnected, l10n.scanner_notConnected,
scheme.onSurfaceVariant, scheme.onSurfaceVariant,
false, false,
), ),
}; };
return Padding( return Padding(
@@ -515,11 +515,7 @@ class _ConnectionStatusHeader extends StatelessWidget {
child: Align( child: Align(
key: ValueKey(connector.state), key: ValueKey(connector.state),
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: StatusChip( child: StatusChip(label: label, color: color, pulse: pulse),
label: label,
color: color,
pulse: pulse,
),
), ),
), ),
); );
+2 -10
View File
@@ -196,11 +196,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
), ),
), ),
if (showChevron) if (showChevron)
Icon( Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 16),
Icons.chevron_right,
color: scheme.onSurfaceVariant,
size: 16,
),
], ],
); );
} }
@@ -694,11 +690,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
], ],
), ),
), ),
Icon( Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 16),
Icons.chevron_right,
color: scheme.onSurfaceVariant,
size: 16,
),
], ],
), ),
), ),
+1 -3
View File
@@ -220,9 +220,7 @@ class _TcpScreenState extends State<TcpScreen> {
if (connector.isTcpTransportConnected) { if (connector.isTcpTransportConnected) {
return StatusChip( return StatusChip(
label: l10n.scanner_connectedTo( label: l10n.scanner_connectedTo(connector.activeTcpEndpoint ?? 'TCP'),
connector.activeTcpEndpoint ?? 'TCP',
),
color: MeshPalette.signal, color: MeshPalette.signal,
); );
} else if (connector.state == MeshCoreConnectionState.connecting && } else if (connector.state == MeshCoreConnectionState.connecting &&
+59 -60
View File
@@ -604,66 +604,68 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
_buildAutoRefreshNumberField( _buildAutoRefreshNumberField(
controller: _autoRefreshIntervalController, controller: _autoRefreshIntervalController,
label: l10n.common_interval, label: l10n.common_interval,
min: _autoRefreshMinIntervalSeconds, min: _autoRefreshMinIntervalSeconds,
max: _autoRefreshMaxIntervalSeconds, max: _autoRefreshMaxIntervalSeconds,
fallback: _autoRefreshIntervalSeconds, fallback: _autoRefreshIntervalSeconds,
),
const SizedBox(height: 12),
_buildAutoRefreshNumberField(
controller: _autoRefreshQuantityController,
label: l10n.telemetry_autoFetchQuantity,
min: _autoRefreshMinQuantity,
max: _autoRefreshMaxQuantity,
fallback: _autoRefreshDefaultQuantity,
),
if (counterText != null) ...[
const SizedBox(height: 12),
Text(
counterText,
textAlign: TextAlign.center,
style: TextStyle(
color: _autoRefreshLastAttemptFailed
? Theme.of(context).colorScheme.error
: null,
fontWeight: FontWeight.w600,
),
), ),
], const SizedBox(height: 12),
const SizedBox(height: 12), _buildAutoRefreshNumberField(
FilledButton( controller: _autoRefreshQuantityController,
onPressed: _isLoading && !_isAutoRefreshEnabled label: l10n.telemetry_autoFetchQuantity,
? null min: _autoRefreshMinQuantity,
: _toggleAutoRefresh, max: _autoRefreshMaxQuantity,
child: _isAutoRefreshEnabled fallback: _autoRefreshDefaultQuantity,
? SizedBox( ),
width: double.infinity, if (counterText != null) ...[
height: 20, const SizedBox(height: 12),
child: Stack( Text(
alignment: Alignment.center, counterText,
children: [ textAlign: TextAlign.center,
Center(child: Text(l10n.common_disable)), style: TextStyle(
Positioned( color: _autoRefreshLastAttemptFailed
right: 0, ? Theme.of(context).colorScheme.error
child: SizedBox( : null,
width: 18, fontWeight: FontWeight.w600,
height: 18, ),
child: CircularProgressIndicator( ),
strokeWidth: 2, ],
color: Theme.of(context).colorScheme.onPrimary, const SizedBox(height: 12),
FilledButton(
onPressed: _isLoading && !_isAutoRefreshEnabled
? null
: _toggleAutoRefresh,
child: _isAutoRefreshEnabled
? SizedBox(
width: double.infinity,
height: 20,
child: Stack(
alignment: Alignment.center,
children: [
Center(child: Text(l10n.common_disable)),
Positioned(
right: 0,
child: SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Theme.of(
context,
).colorScheme.onPrimary,
),
), ),
), ),
), ],
], ),
), )
) : Text(l10n.common_enable),
: Text(l10n.common_enable), ),
), ],
], ),
), ),
), ],
],
); );
} }
@@ -912,10 +914,7 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
value, value,
style: MeshTheme.mono( style: MeshTheme.mono(fontSize: 13, color: scheme.onSurface),
fontSize: 13,
color: scheme.onSurface,
),
textAlign: TextAlign.end, textAlign: TextAlign.end,
), ),
], ],
+3 -11
View File
@@ -108,9 +108,7 @@ class _UsbScreenState extends State<UsbScreen> {
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: Align( child: Align(
key: ValueKey( key: ValueKey('${connector.state}_$_isLoadingPorts'),
'${connector.state}_$_isLoadingPorts',
),
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: _buildStatusChip(context, connector), child: _buildStatusChip(context, connector),
), ),
@@ -230,17 +228,11 @@ class _UsbScreenState extends State<UsbScreen> {
final l10n = context.l10n; final l10n = context.l10n;
if (_isLoadingPorts) { if (_isLoadingPorts) {
return EmptyState( return EmptyState(icon: Icons.usb, title: l10n.usbStatus_searching);
icon: Icons.usb,
title: l10n.usbStatus_searching,
);
} }
if (_ports.isEmpty) { if (_ports.isEmpty) {
return EmptyState( return EmptyState(icon: Icons.usb, title: l10n.usbScreenEmptyState);
icon: Icons.usb,
title: l10n.usbScreenEmptyState,
);
} }
final isConnecting = final isConnecting =
+7 -9
View File
@@ -44,7 +44,8 @@ class RetryServiceConfig {
int messageBytes, { int messageBytes, {
String? contactKey, String? contactKey,
int? deviceTimeoutMs, int? deviceTimeoutMs,
})? calculateTimeout; })?
calculateTimeout;
final Uint8List? Function()? getSelfPublicKey; final Uint8List? Function()? getSelfPublicKey;
final String Function(Contact, String)? prepareContactOutboundText; final String Function(Contact, String)? prepareContactOutboundText;
final AppSettingsService? appSettingsService; final AppSettingsService? appSettingsService;
@@ -436,8 +437,7 @@ class MessageRetryService extends ChangeNotifier {
final outboundTextForTimeout = final outboundTextForTimeout =
config.prepareContactOutboundText?.call(contact, message.text) ?? config.prepareContactOutboundText?.call(contact, message.text) ??
message.text; message.text;
final messageBytesForTimeout = final messageBytesForTimeout = utf8.encode(outboundTextForTimeout).length;
utf8.encode(outboundTextForTimeout).length;
int actualTimeout = timeoutMs; int actualTimeout = timeoutMs;
if (config.calculateTimeout != null) { if (config.calculateTimeout != null) {
@@ -704,13 +704,11 @@ class MessageRetryService extends ChangeNotifier {
tripTimeMs > 0 && tripTimeMs > 0 &&
message.pathLength != null) { message.pathLength != null) {
final outboundTextForObserved = final outboundTextForObserved =
config!.prepareContactOutboundText?.call( config!.prepareContactOutboundText?.call(contact, message.text) ??
contact,
message.text,
) ??
message.text; message.text;
final messageBytesForObserved = final messageBytesForObserved = utf8
utf8.encode(outboundTextForObserved).length; .encode(outboundTextForObserved)
.length;
config.onDeliveryObserved!( config.onDeliveryObserved!(
contact.publicKeyHex, contact.publicKeyHex,
message.pathLength!, message.pathLength!,
+5 -10
View File
@@ -30,7 +30,9 @@ class DeviceTile extends StatelessWidget {
final name = device.platformName.isNotEmpty final name = device.platformName.isNotEmpty
? device.platformName ? device.platformName
: scanResult.advertisementData.advName; : scanResult.advertisementData.advName;
final displayName = name.isNotEmpty ? name : context.l10n.common_unknownDevice; final displayName = name.isNotEmpty
? name
: context.l10n.common_unknownDevice;
final mac = device.remoteId.toString(); final mac = device.remoteId.toString();
final scheme = Theme.of(context).colorScheme; final scheme = Theme.of(context).colorScheme;
@@ -55,11 +57,7 @@ class DeviceTile extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
child: Row( child: Row(
children: [ children: [
AvatarCircle( AvatarCircle(name: displayName, size: 42, icon: Icons.router),
name: displayName,
size: 42,
icon: Icons.router,
),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Column( child: Column(
@@ -107,10 +105,7 @@ class DeviceTile extends StatelessWidget {
const SizedBox(height: 3), const SizedBox(height: 3),
Text( Text(
'$rssi dBm', '$rssi dBm',
style: MeshTheme.mono( style: MeshTheme.mono(fontSize: 10, color: signalUi.color),
fontSize: 10,
color: signalUi.color,
),
), ),
], ],
), ),
+1 -4
View File
@@ -60,10 +60,7 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Switch( Switch(value: widget.value, onChanged: widget.onChanged),
value: widget.value,
onChanged: widget.onChanged,
),
if (widget.hasRefreshing) ...[ if (widget.hasRefreshing) ...[
const SizedBox(width: 4), const SizedBox(width: 4),
widget.isRefreshing widget.isRefreshing
+1 -4
View File
@@ -29,10 +29,7 @@ class JumpToBottomButton extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: scheme.surfaceContainerHigh.withValues(alpha: 0.92), color: scheme.surfaceContainerHigh.withValues(alpha: 0.92),
border: Border.all( border: Border.all(color: scheme.outlineVariant, width: 1),
color: scheme.outlineVariant,
width: 1,
),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withValues(alpha: 0.18), color: Colors.black.withValues(alpha: 0.18),
+6 -12
View File
@@ -350,7 +350,9 @@ class RouteChip extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme; final scheme = Theme.of(context).colorScheme;
final label = isDirect final label = isDirect
? (hops == null || hops == 0 ? 'DIRECT' : '$hops HOP${hops == 1 ? '' : 'S'}') ? (hops == null || hops == 0
? 'DIRECT'
: '$hops HOP${hops == 1 ? '' : 'S'}')
: 'FLOOD'; : 'FLOOD';
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
@@ -536,9 +538,7 @@ Future<T?> showMeshSheet<T>(
useSafeArea: true, useSafeArea: true,
showDragHandle: false, showDragHandle: false,
builder: (context) => Padding( builder: (context) => Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom),
bottom: MediaQuery.viewInsetsOf(context).bottom,
),
child: builder(context), child: builder(context),
), ),
); );
@@ -574,10 +574,7 @@ class ErrorRetryCard extends StatelessWidget {
), ),
), ),
if (onRetry != null) if (onRetry != null)
TextButton( TextButton(onPressed: onRetry, child: Text(retryLabel ?? 'Retry')),
onPressed: onRetry,
child: Text(retryLabel ?? 'Retry'),
),
], ],
), ),
); );
@@ -610,10 +607,7 @@ class _ListEntranceState extends State<ListEntrance>
vsync: this, vsync: this,
duration: const Duration(milliseconds: 280), duration: const Duration(milliseconds: 280),
); );
_curve = CurvedAnimation( _curve = CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic);
parent: _controller,
curve: Curves.easeOutCubic,
);
final delay = Duration(milliseconds: 24 * widget.index.clamp(0, 12)); final delay = Duration(milliseconds: 24 * widget.index.clamp(0, 12));
Future.delayed(delay, () { Future.delayed(delay, () {
if (mounted) _controller.forward(); if (mounted) _controller.forward();
+1 -5
View File
@@ -72,11 +72,7 @@ class _MessageStatusIconState extends State<MessageStatusIcon>
if (widget.isFailed) { if (widget.isFailed) {
return Semantics( return Semantics(
label: l10n.messageStatus_failed, label: l10n.messageStatus_failed,
child: Icon( child: Icon(Icons.cancel, size: size, color: colorScheme.error),
Icons.cancel,
size: size,
color: colorScheme.error,
),
); );
} }
+8 -6
View File
@@ -160,10 +160,7 @@ List<Polyline> buildPacketTrailPolylines(
} }
/// The moving packet dot and the pulse ring at the hop it just reached. /// The moving packet dot and the pulse ring at the hop it just reached.
List<Marker> buildPacketMarkers( List<Marker> buildPacketMarkers(PathPlaybackController playback, Color color) {
PathPlaybackController playback,
Color color,
) {
if (!playback.started || !playback.hasPath) return const []; if (!playback.started || !playback.hasPath) return const [];
final markers = <Marker>[]; final markers = <Marker>[];
@@ -412,7 +409,9 @@ class PathAnimationControls extends StatelessWidget {
), ),
controlButton( controlButton(
icon: playback.playing ? Icons.pause : Icons.play_arrow, icon: playback.playing ? Icons.pause : Icons.play_arrow,
tooltip: playback.playing ? l10n.pathMap_pause : l10n.pathMap_play, tooltip: playback.playing
? l10n.pathMap_pause
: l10n.pathMap_play,
onPressed: enabled ? playback.togglePlay : null, onPressed: enabled ? playback.togglePlay : null,
), ),
controlButton( controlButton(
@@ -635,7 +634,10 @@ class PathSummaryList extends StatelessWidget {
parts.join(' · '), parts.join(' · '),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: MeshTheme.mono(fontSize: 10.5, color: MeshPalette.ink3), style: MeshTheme.mono(
fontSize: 10.5,
color: MeshPalette.ink3,
),
), ),
), ),
), ),
+4 -15
View File
@@ -332,19 +332,12 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Icon( Icon(Icons.error, size: 18, color: scheme.error),
Icons.error,
size: 18,
color: scheme.error,
),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(
_loginError!, _loginError!,
style: TextStyle( style: TextStyle(color: scheme.error, fontSize: 13),
color: scheme.error,
fontSize: 13,
),
), ),
), ),
], ],
@@ -435,9 +428,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
Icon( Icon(
Icons.auto_mode, Icons.auto_mode,
size: 20, size: 20,
color: !isFloodMode color: !isFloodMode ? scheme.primary : null,
? scheme.primary
: null,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
@@ -458,9 +449,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
Icon( Icon(
Icons.waves, Icons.waves,
size: 20, size: 20,
color: isFloodMode color: isFloodMode ? scheme.primary : null,
? scheme.primary
: null,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
+2 -6
View File
@@ -364,9 +364,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
Icon( Icon(
Icons.auto_mode, Icons.auto_mode,
size: 20, size: 20,
color: !isFloodMode color: !isFloodMode ? scheme.primary : null,
? scheme.primary
: null,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
@@ -387,9 +385,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
Icon( Icon(
Icons.waves, Icons.waves,
size: 20, size: 20,
color: isFloodMode color: isFloodMode ? scheme.primary : null,
? scheme.primary
: null,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
+2 -8
View File
@@ -15,10 +15,7 @@ class UnreadDivider extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
child: Container( child: Container(height: 1, color: color.withValues(alpha: 0.25)),
height: 1,
color: color.withValues(alpha: 0.25),
),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Container( Container(
@@ -39,10 +36,7 @@ class UnreadDivider extends StatelessWidget {
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded( Expanded(
child: Container( child: Container(height: 1, color: color.withValues(alpha: 0.25)),
height: 1,
color: color.withValues(alpha: 0.25),
),
), ),
], ],
), ),