mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-06-14 22:55:12 +10:00
format files
This commit is contained in:
@@ -30,87 +30,103 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
),
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
child: Consumer3<AppSettingsService, MeshCoreConnector,
|
||||
TranslationService>(
|
||||
builder: (
|
||||
context,
|
||||
settingsService,
|
||||
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),
|
||||
),
|
||||
|
||||
// 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(
|
||||
child:
|
||||
Consumer3<
|
||||
AppSettingsService,
|
||||
MeshCoreConnector,
|
||||
TranslationService
|
||||
>(
|
||||
builder:
|
||||
(
|
||||
context,
|
||||
settingsService,
|
||||
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
|
||||
SectionHeader(context.l10n.appSettings_mapDisplay),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildMapContent(context, settingsService),
|
||||
),
|
||||
// NOTIFICATIONS
|
||||
SectionHeader(context.l10n.appSettings_notifications),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildNotificationsContent(
|
||||
context,
|
||||
settingsService,
|
||||
),
|
||||
),
|
||||
|
||||
// TRANSLATION (non-web only)
|
||||
if (!kIsWeb) ...[
|
||||
SectionHeader(context.l10n.translation_title),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildTranslationContent(
|
||||
context,
|
||||
settingsService,
|
||||
translationService,
|
||||
),
|
||||
),
|
||||
],
|
||||
// MESSAGING
|
||||
SectionHeader(context.l10n.appSettings_messaging),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildMessagingContent(
|
||||
context,
|
||||
settingsService,
|
||||
),
|
||||
),
|
||||
|
||||
// CYR2LAT
|
||||
SectionHeader(context.l10n.channels_cyr2latSettingsHeading),
|
||||
MeshCard(
|
||||
padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
|
||||
child: _buildCyr2LatContent(context, settingsService),
|
||||
),
|
||||
// BATTERY
|
||||
SectionHeader(context.l10n.appSettings_battery),
|
||||
MeshCard(
|
||||
padding: const EdgeInsets.fromLTRB(16, 4, 16, 16),
|
||||
child: _buildBatteryContent(
|
||||
context,
|
||||
settingsService,
|
||||
connector,
|
||||
),
|
||||
),
|
||||
|
||||
// DEBUG
|
||||
SectionHeader(context.l10n.appSettings_debugCard),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildDebugContent(context, settingsService),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
// MAP
|
||||
SectionHeader(context.l10n.appSettings_mapDisplay),
|
||||
MeshCard(
|
||||
padding: EdgeInsets.zero,
|
||||
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,
|
||||
onChanged: notifEnabled
|
||||
? (value) =>
|
||||
settingsService.setNotifyOnNewChannelMessage(value)
|
||||
? (value) => settingsService.setNotifyOnNewChannelMessage(value)
|
||||
: null,
|
||||
),
|
||||
const Divider(height: 1, indent: 16),
|
||||
@@ -367,9 +382,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
),
|
||||
secondary: const Icon(Icons.refresh_outlined, size: 20),
|
||||
title: Text(context.l10n.appSettings_clearPathOnMaxRetry),
|
||||
subtitle: Text(
|
||||
context.l10n.appSettings_clearPathOnMaxRetrySubtitle,
|
||||
),
|
||||
subtitle: Text(context.l10n.appSettings_clearPathOnMaxRetrySubtitle),
|
||||
value: settingsService.settings.clearPathOnMaxRetry,
|
||||
onChanged: (value) {
|
||||
settingsService.setClearPathOnMaxRetry(value);
|
||||
@@ -472,9 +485,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
min: 0.5,
|
||||
max: 5.0,
|
||||
divisions: 9,
|
||||
label: settingsService
|
||||
.settings
|
||||
.initialRouteWeight
|
||||
label: settingsService.settings.initialRouteWeight
|
||||
.toStringAsFixed(1),
|
||||
onChanged: (value) =>
|
||||
settingsService.setInitialRouteWeight(value),
|
||||
@@ -485,9 +496,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
context
|
||||
.l10n
|
||||
.appSettings_routeWeightSuccessIncrement,
|
||||
context.l10n.appSettings_routeWeightSuccessIncrement,
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -517,9 +526,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
context
|
||||
.l10n
|
||||
.appSettings_routeWeightFailureDecrement,
|
||||
context.l10n.appSettings_routeWeightFailureDecrement,
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -548,9 +555,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(
|
||||
context.l10n.appSettings_maxMessageRetries,
|
||||
),
|
||||
title: Text(context.l10n.appSettings_maxMessageRetries),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -560,16 +565,12 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
.appSettings_maxMessageRetriesSubtitle,
|
||||
),
|
||||
Slider(
|
||||
value: settingsService
|
||||
.settings
|
||||
.maxMessageRetries
|
||||
value: settingsService.settings.maxMessageRetries
|
||||
.toDouble(),
|
||||
min: 2,
|
||||
max: 10,
|
||||
divisions: 8,
|
||||
label: settingsService
|
||||
.settings
|
||||
.maxMessageRetries
|
||||
label: settingsService.settings.maxMessageRetries
|
||||
.toString(),
|
||||
onChanged: (value) => settingsService
|
||||
.setMaxMessageRetries(value.toInt()),
|
||||
@@ -590,9 +591,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
),
|
||||
secondary: const Icon(Icons.location_searching, size: 20),
|
||||
title: Text(context.l10n.appSettings_enableMessageTracing),
|
||||
subtitle: Text(
|
||||
context.l10n.appSettings_enableMessageTracingSubtitle,
|
||||
),
|
||||
subtitle: Text(context.l10n.appSettings_enableMessageTracingSubtitle),
|
||||
value: settingsService.settings.enableMessageTracing,
|
||||
onChanged: (value) {
|
||||
settingsService.setEnableMessageTracing(value);
|
||||
@@ -765,9 +764,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
settingsService.settings.mapTimeFilterHours == 0
|
||||
? context.l10n.appSettings_timeFilterShowAll
|
||||
: context.l10n.appSettings_timeFilterShowLast(
|
||||
settingsService
|
||||
.settings
|
||||
.mapTimeFilterHours
|
||||
settingsService.settings.mapTimeFilterHours
|
||||
.toInt(),
|
||||
),
|
||||
style: textTheme.bodySmall?.copyWith(
|
||||
@@ -925,15 +922,17 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
title: Text(
|
||||
context.l10n.translation_autoIncomingTitle,
|
||||
style: TextStyle(
|
||||
color:
|
||||
translationEnabled ? null : Theme.of(context).disabledColor,
|
||||
color: translationEnabled
|
||||
? null
|
||||
: Theme.of(context).disabledColor,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
context.l10n.translation_autoIncomingSubtitle,
|
||||
style: TextStyle(
|
||||
color:
|
||||
translationEnabled ? null : Theme.of(context).disabledColor,
|
||||
color: translationEnabled
|
||||
? null
|
||||
: Theme.of(context).disabledColor,
|
||||
),
|
||||
),
|
||||
value: settings.autoTranslateIncomingMessages,
|
||||
@@ -955,15 +954,17 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
title: Text(
|
||||
context.l10n.translation_composerTitle,
|
||||
style: TextStyle(
|
||||
color:
|
||||
translationEnabled ? null : Theme.of(context).disabledColor,
|
||||
color: translationEnabled
|
||||
? null
|
||||
: Theme.of(context).disabledColor,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
context.l10n.translation_composerSubtitle,
|
||||
style: TextStyle(
|
||||
color:
|
||||
translationEnabled ? null : Theme.of(context).disabledColor,
|
||||
color: translationEnabled
|
||||
? null
|
||||
: Theme.of(context).disabledColor,
|
||||
),
|
||||
),
|
||||
value: settings.composerTranslationEnabled,
|
||||
@@ -973,17 +974,12 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
),
|
||||
const Divider(height: 1, indent: 16),
|
||||
InkWell(
|
||||
onTap: () =>
|
||||
_showTranslationLanguageDialog(context, settingsService),
|
||||
onTap: () => _showTranslationLanguageDialog(context, settingsService),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.language,
|
||||
size: 20,
|
||||
color: scheme.onSurfaceVariant,
|
||||
),
|
||||
Icon(Icons.language, size: 20, color: scheme.onSurfaceVariant),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
@@ -1106,7 +1102,8 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
child: LinearProgressIndicator(
|
||||
value: translationService.downloadFileName ==
|
||||
value:
|
||||
translationService.downloadFileName ==
|
||||
'Merging chunks...'
|
||||
? null
|
||||
: translationService.downloadProgress,
|
||||
@@ -1151,8 +1148,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
BorderRadius.circular(MeshRadii.xs),
|
||||
borderRadius: BorderRadius.circular(MeshRadii.xs),
|
||||
onTap: () => settingsService
|
||||
.setTranslationSelectedModelId(model.id),
|
||||
child: Column(
|
||||
@@ -1194,9 +1190,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
translationService.lastError!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
),
|
||||
],
|
||||
],
|
||||
@@ -1373,8 +1367,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageEn,
|
||||
value: 'en',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'en',
|
||||
selected: settingsService.settings.languageOverride == 'en',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('en');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1384,8 +1377,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageFr,
|
||||
value: 'fr',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'fr',
|
||||
selected: settingsService.settings.languageOverride == 'fr',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('fr');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1395,8 +1387,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageEs,
|
||||
value: 'es',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'es',
|
||||
selected: settingsService.settings.languageOverride == 'es',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('es');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1406,8 +1397,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageDe,
|
||||
value: 'de',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'de',
|
||||
selected: settingsService.settings.languageOverride == 'de',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('de');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1417,8 +1407,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languagePl,
|
||||
value: 'pl',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'pl',
|
||||
selected: settingsService.settings.languageOverride == 'pl',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('pl');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1428,8 +1417,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageSl,
|
||||
value: 'sl',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'sl',
|
||||
selected: settingsService.settings.languageOverride == 'sl',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('sl');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1439,8 +1427,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languagePt,
|
||||
value: 'pt',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'pt',
|
||||
selected: settingsService.settings.languageOverride == 'pt',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('pt');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1450,8 +1437,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageIt,
|
||||
value: 'it',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'it',
|
||||
selected: settingsService.settings.languageOverride == 'it',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('it');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1461,8 +1447,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageZh,
|
||||
value: 'zh',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'zh',
|
||||
selected: settingsService.settings.languageOverride == 'zh',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('zh');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1472,8 +1457,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageSv,
|
||||
value: 'sv',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'sv',
|
||||
selected: settingsService.settings.languageOverride == 'sv',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('sv');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1483,8 +1467,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageNl,
|
||||
value: 'nl',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'nl',
|
||||
selected: settingsService.settings.languageOverride == 'nl',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('nl');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1494,8 +1477,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageSk,
|
||||
value: 'sk',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'sk',
|
||||
selected: settingsService.settings.languageOverride == 'sk',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('sk');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1505,8 +1487,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageBg,
|
||||
value: 'bg',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'bg',
|
||||
selected: settingsService.settings.languageOverride == 'bg',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('bg');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1516,8 +1497,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageRu,
|
||||
value: 'ru',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'ru',
|
||||
selected: settingsService.settings.languageOverride == 'ru',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('ru');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1527,8 +1507,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageUk,
|
||||
value: 'uk',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'uk',
|
||||
selected: settingsService.settings.languageOverride == 'uk',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('uk');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1538,8 +1517,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageHu,
|
||||
value: 'hu',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'hu',
|
||||
selected: settingsService.settings.languageOverride == 'hu',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('hu');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1549,8 +1527,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageJa,
|
||||
value: 'ja',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'ja',
|
||||
selected: settingsService.settings.languageOverride == 'ja',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('ja');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1560,8 +1537,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_languageKo,
|
||||
value: 'ko',
|
||||
selected:
|
||||
settingsService.settings.languageOverride == 'ko',
|
||||
selected: settingsService.settings.languageOverride == 'ko',
|
||||
onTap: () {
|
||||
settingsService.setLanguageOverride('ko');
|
||||
Navigator.pop(ctx);
|
||||
@@ -1660,8 +1636,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
ctx,
|
||||
label: context.l10n.appSettings_unitsMetric,
|
||||
value: UnitSystem.metric,
|
||||
selected:
|
||||
settingsService.settings.unitSystem == UnitSystem.metric,
|
||||
selected: settingsService.settings.unitSystem == UnitSystem.metric,
|
||||
onTap: () {
|
||||
settingsService.setUnitSystem(UnitSystem.metric);
|
||||
Navigator.pop(ctx);
|
||||
@@ -1874,9 +1849,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
if (nameController.text.isEmpty) {
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
content: Text(
|
||||
context.l10n.settings_cyr2latProfileNameEmpty,
|
||||
),
|
||||
content: Text(context.l10n.settings_cyr2latProfileNameEmpty),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -1964,9 +1937,7 @@ class AppSettingsScreen extends StatelessWidget {
|
||||
if (nameController.text.isEmpty) {
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
content: Text(
|
||||
context.l10n.settings_cyr2latProfileNameEmpty,
|
||||
),
|
||||
content: Text(context.l10n.settings_cyr2latProfileNameEmpty),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -462,7 +462,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
color: MeshPalette.magenta,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceContainerLow,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
@@ -488,9 +490,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
Expanded(
|
||||
child: Text(
|
||||
channelLabel,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
style: Theme.of(context).textTheme.bodyMedium
|
||||
?.copyWith(fontWeight: FontWeight.w500),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -544,8 +545,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (unreadCount > 0)
|
||||
UnreadBadge(count: unreadCount),
|
||||
if (unreadCount > 0) UnreadBadge(count: unreadCount),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -806,12 +806,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
return MeshCard(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
borderColor: isSelected && enabled
|
||||
? MeshPalette.blueLine
|
||||
: null,
|
||||
color: isSelected && enabled
|
||||
? MeshPalette.blueBg
|
||||
: null,
|
||||
borderColor: isSelected && enabled ? MeshPalette.blueLine : null,
|
||||
color: isSelected && enabled ? MeshPalette.blueBg : null,
|
||||
onTap: enabled
|
||||
? () {
|
||||
setSheetState(() {
|
||||
@@ -828,7 +824,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
name: title,
|
||||
size: 38,
|
||||
color: enabled
|
||||
? (isSelected ? MeshPalette.blue : cardScheme.onSurfaceVariant)
|
||||
? (isSelected
|
||||
? MeshPalette.blue
|
||||
: cardScheme.onSurfaceVariant)
|
||||
: cardScheme.outline,
|
||||
icon: icon,
|
||||
),
|
||||
@@ -840,17 +838,21 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(sheetContext).textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: enabled ? null : cardScheme.outline,
|
||||
),
|
||||
style: Theme.of(sheetContext).textTheme.bodyMedium
|
||||
?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: enabled ? null : cardScheme.outline,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
subtitle,
|
||||
style: Theme.of(sheetContext).textTheme.bodySmall?.copyWith(
|
||||
color: enabled ? cardScheme.onSurfaceVariant : cardScheme.outline,
|
||||
),
|
||||
style: Theme.of(sheetContext).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: enabled
|
||||
? cardScheme.onSurfaceVariant
|
||||
: cardScheme.outline,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -860,7 +862,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
if (enabled)
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: isSelected ? MeshPalette.blue : cardScheme.onSurfaceVariant,
|
||||
color: isSelected
|
||||
? MeshPalette.blue
|
||||
: cardScheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
@@ -998,9 +1002,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
content: Text(
|
||||
sheetContext
|
||||
.l10n
|
||||
.channels_pskMustBe32Hex,
|
||||
sheetContext.l10n.channels_pskMustBe32Hex,
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -1313,9 +1315,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
addPublicChannel = value ?? true;
|
||||
});
|
||||
},
|
||||
title: Text(
|
||||
sheetContext.l10n.community_addPublicChannel,
|
||||
),
|
||||
title: Text(sheetContext.l10n.community_addPublicChannel),
|
||||
subtitle: Text(
|
||||
sheetContext.l10n.community_addPublicChannelHint,
|
||||
),
|
||||
@@ -1418,9 +1418,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
maxChildSize: 0.95,
|
||||
builder: (_, scrollController) => Column(
|
||||
children: [
|
||||
BottomSheetHeader(
|
||||
title: sheetContext.l10n.channels_addChannel,
|
||||
),
|
||||
BottomSheetHeader(title: sheetContext.l10n.channels_addChannel),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
controller: scrollController,
|
||||
@@ -1519,7 +1517,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
builder: (_, scrollController) => Column(
|
||||
children: [
|
||||
BottomSheetHeader(
|
||||
title: sheetContext.l10n.channels_editChannelTitle(channel.index),
|
||||
title: sheetContext.l10n.channels_editChannelTitle(
|
||||
channel.index,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
@@ -1569,7 +1569,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
),
|
||||
SwitchListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(sheetContext.l10n.channels_cyr2latCompression),
|
||||
title: Text(
|
||||
sheetContext.l10n.channels_cyr2latCompression,
|
||||
),
|
||||
subtitle: Text(
|
||||
sheetContext.l10n.channels_cyr2latCompressionDscr,
|
||||
),
|
||||
@@ -1592,14 +1594,14 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
.channels_cyr2latSettingsSubheading,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
items: appSettingsService.settings.cyr2latProfiles.map((
|
||||
profile,
|
||||
) {
|
||||
return DropdownMenuItem(
|
||||
value: profile.id,
|
||||
child: Text(profile.name),
|
||||
);
|
||||
}).toList(),
|
||||
items: appSettingsService.settings.cyr2latProfiles
|
||||
.map((profile) {
|
||||
return DropdownMenuItem(
|
||||
value: profile.id,
|
||||
child: Text(profile.name),
|
||||
);
|
||||
})
|
||||
.toList(),
|
||||
onChanged: (value) => setSheetState(() {
|
||||
selectedCyr2LatProfileId = value;
|
||||
}),
|
||||
@@ -1633,14 +1635,20 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
} on FormatException {
|
||||
showDismissibleSnackBar(
|
||||
sheetContext,
|
||||
content: Text(sheetContext.l10n.channels_pskMustBe32Hex),
|
||||
content: Text(
|
||||
sheetContext.l10n.channels_pskMustBe32Hex,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.pop(sheetContext);
|
||||
try {
|
||||
await connector.setChannel(channel.index, name, psk);
|
||||
await connector.setChannel(
|
||||
channel.index,
|
||||
name,
|
||||
psk,
|
||||
);
|
||||
await connector.setChannelSmazEnabled(
|
||||
channel.index,
|
||||
smazEnabled,
|
||||
@@ -1656,7 +1664,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
if (!context.mounted) return;
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
content: Text(context.l10n.channels_channelUpdated(name)),
|
||||
content: Text(
|
||||
context.l10n.channels_channelUpdated(name),
|
||||
),
|
||||
);
|
||||
} catch (e, st) {
|
||||
debugPrint(st.toString());
|
||||
@@ -1732,7 +1742,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
},
|
||||
child: Text(
|
||||
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(
|
||||
dialogContext.l10n.community_delete,
|
||||
style: TextStyle(color: Theme.of(dialogContext).colorScheme.error),
|
||||
style: TextStyle(
|
||||
color: Theme.of(dialogContext).colorScheme.error,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -109,10 +109,7 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
|
||||
),
|
||||
child: Text(
|
||||
context.l10n.community_scanInstructions,
|
||||
style: const TextStyle(
|
||||
color: MeshPalette.ink2,
|
||||
fontSize: 13,
|
||||
),
|
||||
style: const TextStyle(color: MeshPalette.ink2, fontSize: 13),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
@@ -185,61 +182,61 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
|
||||
builder: (sheetContext) {
|
||||
final sheetScheme = Theme.of(sheetContext).colorScheme;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
BottomSheetHeader(title: context.l10n.community_alreadyMember),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
|
||||
child: Text(
|
||||
context.l10n.community_alreadyMemberMessage(community.name),
|
||||
style: TextStyle(color: sheetScheme.onSurfaceVariant),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
BottomSheetHeader(title: context.l10n.community_alreadyMember),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
|
||||
child: Text(
|
||||
context.l10n.community_alreadyMemberMessage(community.name),
|
||||
style: TextStyle(color: sheetScheme.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
),
|
||||
MeshCard(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.groups,
|
||||
color: MeshPalette.magenta,
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
MeshCard(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.groups,
|
||||
color: MeshPalette.magenta,
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(sheetContext);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.l10n.common_ok),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||
child: FilledButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(sheetContext);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.l10n.common_ok),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -258,90 +255,90 @@ class _CommunityQrScannerScreenState extends State<CommunityQrScannerScreen> {
|
||||
builder: (sheetContext, setSheetState) {
|
||||
final joinScheme = Theme.of(sheetContext).colorScheme;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
BottomSheetHeader(title: context.l10n.community_joinTitle),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
|
||||
child: Text(
|
||||
context.l10n.community_joinConfirmation(community.name),
|
||||
style: TextStyle(color: joinScheme.onSurfaceVariant),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
BottomSheetHeader(title: context.l10n.community_joinTitle),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 4),
|
||||
child: Text(
|
||||
context.l10n.community_joinConfirmation(community.name),
|
||||
style: TextStyle(color: joinScheme.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
),
|
||||
MeshCard(
|
||||
child: Row(
|
||||
children: [
|
||||
AvatarCircle(
|
||||
name: community.name,
|
||||
icon: Icons.groups,
|
||||
color: MeshPalette.magenta,
|
||||
size: 44,
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
community.name,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 15,
|
||||
MeshCard(
|
||||
child: Row(
|
||||
children: [
|
||||
AvatarCircle(
|
||||
name: community.name,
|
||||
icon: Icons.groups,
|
||||
color: MeshPalette.magenta,
|
||||
size: 44,
|
||||
),
|
||||
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: joinScheme.onSurfaceVariant,
|
||||
Text(
|
||||
'ID: ${community.shortCommunityId}...',
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 11.5,
|
||||
color: joinScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
CheckboxListTile(
|
||||
value: addPublicChannel,
|
||||
onChanged: (value) {
|
||||
setSheetState(() {
|
||||
addPublicChannel = value ?? true;
|
||||
});
|
||||
},
|
||||
title: Text(context.l10n.community_addPublicChannel),
|
||||
subtitle: Text(context.l10n.community_addPublicChannelHint),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
CheckboxListTile(
|
||||
value: addPublicChannel,
|
||||
onChanged: (value) {
|
||||
setSheetState(() {
|
||||
addPublicChannel = value ?? true;
|
||||
});
|
||||
},
|
||||
title: Text(context.l10n.community_addPublicChannel),
|
||||
subtitle: Text(context.l10n.community_addPublicChannelHint),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -139,10 +139,7 @@ class _CompanionRadioStatsScreenState extends State<CompanionRadioStatsScreen> {
|
||||
stats.lastSnrDb.toStringAsFixed(1),
|
||||
),
|
||||
Icons.signal_cellular_alt,
|
||||
MeshTheme.snrColor(
|
||||
stats.lastSnrDb,
|
||||
blocked: false,
|
||||
),
|
||||
MeshTheme.snrColor(stats.lastSnrDb, blocked: false),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1574,7 +1574,8 @@ class _ContactTile extends StatelessWidget {
|
||||
case advTypeSensor:
|
||||
return const Color(0xFF4ACCC4); // teal
|
||||
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(
|
||||
Icons.location_on,
|
||||
size: 13,
|
||||
color: scheme.onSurfaceVariant.withValues(alpha: 0.55),
|
||||
color: scheme.onSurfaceVariant.withValues(
|
||||
alpha: 0.55,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -351,10 +351,7 @@ class _NeighborsScreenState extends State<NeighborsScreen> {
|
||||
for (var i = 0; i < _parsedNeighbors!.length; i++)
|
||||
ListEntrance(
|
||||
index: i,
|
||||
child: _buildNeighborRow(
|
||||
_parsedNeighbors![i],
|
||||
connector.currentSf,
|
||||
),
|
||||
child: _buildNeighborRow(_parsedNeighbors![i], connector.currentSf),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -801,9 +801,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen>
|
||||
final selected = _selectedPath;
|
||||
return selected != null ? [selected] : const [];
|
||||
}
|
||||
return _displayPaths
|
||||
.where((p) => !_hiddenPathIds.contains(p.id))
|
||||
.toList();
|
||||
return _displayPaths.where((p) => !_hiddenPathIds.contains(p.id)).toList();
|
||||
}
|
||||
|
||||
/// 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();
|
||||
showSharedNodeSheet(
|
||||
context,
|
||||
title: '$hex: ${contact?.name ?? context.l10n.channelPath_unknownRepeater}',
|
||||
title:
|
||||
'$hex: ${contact?.name ?? context.l10n.channelPath_unknownRepeater}',
|
||||
paths: paths,
|
||||
onSelect: _selectPath,
|
||||
);
|
||||
@@ -1539,9 +1538,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen>
|
||||
tooltip: _panelCollapsed
|
||||
? l10n.pathMap_expandPanel
|
||||
: l10n.pathMap_collapsePanel,
|
||||
onPressed: () => setState(
|
||||
() => _panelCollapsed = !_panelCollapsed,
|
||||
),
|
||||
onPressed: () =>
|
||||
setState(() => _panelCollapsed = !_panelCollapsed),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -470,26 +470,16 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.terminal,
|
||||
size: 48,
|
||||
color: MeshPalette.ink4,
|
||||
),
|
||||
const Icon(Icons.terminal, size: 48, color: MeshPalette.ink4),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
l10n.repeater_noCommandsSent,
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 13,
|
||||
color: MeshPalette.ink3,
|
||||
),
|
||||
style: MeshTheme.mono(fontSize: 13, color: MeshPalette.ink3),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
l10n.repeater_typeCommandOrUseQuick,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: MeshPalette.ink4,
|
||||
),
|
||||
style: const TextStyle(fontSize: 12, color: MeshPalette.ink4),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -518,9 +508,7 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isCommand
|
||||
? MeshPalette.blue
|
||||
: MeshPalette.ink3,
|
||||
color: isCommand ? MeshPalette.blue : MeshPalette.ink3,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -530,9 +518,7 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
|
||||
entry['text']!,
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 12.5,
|
||||
color: isCommand
|
||||
? MeshPalette.blue
|
||||
: MeshPalette.ink,
|
||||
color: isCommand ? MeshPalette.blue : MeshPalette.ink,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -559,156 +545,522 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
|
||||
void _showCommandHelp(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
final generalCommands = [
|
||||
_CommandHelpEntry(command: 'advert', description: l10n.repeater_cliHelpAdvert),
|
||||
_CommandHelpEntry(command: 'reboot', description: l10n.repeater_cliHelpReboot),
|
||||
_CommandHelpEntry(command: 'clock', description: l10n.repeater_cliHelpClock),
|
||||
_CommandHelpEntry(command: 'password {new-password}', description: l10n.repeater_cliHelpPassword),
|
||||
_CommandHelpEntry(command: 'ver', description: l10n.repeater_cliHelpVersion),
|
||||
_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),
|
||||
_CommandHelpEntry(
|
||||
command: 'advert',
|
||||
description: l10n.repeater_cliHelpAdvert,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'reboot',
|
||||
description: l10n.repeater_cliHelpReboot,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'clock',
|
||||
description: l10n.repeater_cliHelpClock,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'password {new-password}',
|
||||
description: l10n.repeater_cliHelpPassword,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'ver',
|
||||
description: l10n.repeater_cliHelpVersion,
|
||||
),
|
||||
_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 = [
|
||||
_CommandHelpEntry(command: 'set af {air-time-factor}', description: l10n.repeater_cliHelpSetAf),
|
||||
_CommandHelpEntry(command: 'set tx {tx-power-dbm}', description: l10n.repeater_cliHelpSetTx),
|
||||
_CommandHelpEntry(command: 'set repeat {on|off}', description: l10n.repeater_cliHelpSetRepeat),
|
||||
_CommandHelpEntry(command: 'set allow.read.only {on|off}', description: l10n.repeater_cliHelpSetAllowReadOnly),
|
||||
_CommandHelpEntry(command: 'set flood.max {max-hops}', description: l10n.repeater_cliHelpSetFloodMax),
|
||||
_CommandHelpEntry(command: 'set int.thresh {db}', description: l10n.repeater_cliHelpSetIntThresh),
|
||||
_CommandHelpEntry(command: 'set agc.reset.interval {seconds}', description: l10n.repeater_cliHelpSetAgcResetInterval),
|
||||
_CommandHelpEntry(command: 'set multi.acks {0|1}', description: l10n.repeater_cliHelpSetMultiAcks),
|
||||
_CommandHelpEntry(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),
|
||||
_CommandHelpEntry(
|
||||
command: 'set af {air-time-factor}',
|
||||
description: l10n.repeater_cliHelpSetAf,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set tx {tx-power-dbm}',
|
||||
description: l10n.repeater_cliHelpSetTx,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set repeat {on|off}',
|
||||
description: l10n.repeater_cliHelpSetRepeat,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set allow.read.only {on|off}',
|
||||
description: l10n.repeater_cliHelpSetAllowReadOnly,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set flood.max {max-hops}',
|
||||
description: l10n.repeater_cliHelpSetFloodMax,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set int.thresh {db}',
|
||||
description: l10n.repeater_cliHelpSetIntThresh,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set agc.reset.interval {seconds}',
|
||||
description: l10n.repeater_cliHelpSetAgcResetInterval,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'set multi.acks {0|1}',
|
||||
description: l10n.repeater_cliHelpSetMultiAcks,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
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 = [
|
||||
_CommandHelpEntry(command: 'get bridge.type', description: l10n.repeater_cliHelpGetBridgeType),
|
||||
_CommandHelpEntry(
|
||||
command: 'get bridge.type',
|
||||
description: l10n.repeater_cliHelpGetBridgeType,
|
||||
),
|
||||
];
|
||||
|
||||
final loggingCommands = [
|
||||
_CommandHelpEntry(command: 'log start', description: l10n.repeater_cliHelpLogStart),
|
||||
_CommandHelpEntry(command: 'log stop', description: l10n.repeater_cliHelpLogStop),
|
||||
_CommandHelpEntry(command: 'log erase', description: l10n.repeater_cliHelpLogErase),
|
||||
_CommandHelpEntry(
|
||||
command: 'log start',
|
||||
description: l10n.repeater_cliHelpLogStart,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'log stop',
|
||||
description: l10n.repeater_cliHelpLogStop,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'log erase',
|
||||
description: l10n.repeater_cliHelpLogErase,
|
||||
),
|
||||
];
|
||||
|
||||
final neighborCommands = [
|
||||
_CommandHelpEntry(command: 'neighbors', description: l10n.repeater_cliHelpNeighbors),
|
||||
_CommandHelpEntry(command: 'neighbor.remove {pubkey-prefix}', description: l10n.repeater_cliHelpNeighborRemove),
|
||||
_CommandHelpEntry(
|
||||
command: 'neighbors',
|
||||
description: l10n.repeater_cliHelpNeighbors,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'neighbor.remove {pubkey-prefix}',
|
||||
description: l10n.repeater_cliHelpNeighborRemove,
|
||||
),
|
||||
];
|
||||
|
||||
final regionCommands = [
|
||||
_CommandHelpEntry(command: 'region', description: l10n.repeater_cliHelpRegion),
|
||||
_CommandHelpEntry(command: 'region load', description: l10n.repeater_cliHelpRegionLoad),
|
||||
_CommandHelpEntry(command: 'region get {* | name-prefix}', description: l10n.repeater_cliHelpRegionGet),
|
||||
_CommandHelpEntry(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),
|
||||
_CommandHelpEntry(
|
||||
command: 'region',
|
||||
description: l10n.repeater_cliHelpRegion,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'region load',
|
||||
description: l10n.repeater_cliHelpRegionLoad,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'region get {* | name-prefix}',
|
||||
description: l10n.repeater_cliHelpRegionGet,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
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 = [
|
||||
_CommandHelpEntry(command: 'get name', description: l10n.repeater_cliHelpGetName),
|
||||
_CommandHelpEntry(command: 'get role', description: l10n.repeater_cliHelpGetRole),
|
||||
_CommandHelpEntry(command: 'get public.key', description: l10n.repeater_cliHelpGetPublicKey),
|
||||
_CommandHelpEntry(command: 'get prv.key', description: l10n.repeater_cliHelpGetPrvKey),
|
||||
_CommandHelpEntry(command: 'get repeat', description: l10n.repeater_cliHelpGetRepeat),
|
||||
_CommandHelpEntry(command: 'get tx', description: l10n.repeater_cliHelpGetTx),
|
||||
_CommandHelpEntry(command: 'get freq', description: l10n.repeater_cliHelpGetFreq),
|
||||
_CommandHelpEntry(command: 'get radio', description: l10n.repeater_cliHelpGetRadio),
|
||||
_CommandHelpEntry(command: 'get radio.rxgain', description: l10n.repeater_cliHelpGetRadioRxGain),
|
||||
_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),
|
||||
_CommandHelpEntry(
|
||||
command: 'get name',
|
||||
description: l10n.repeater_cliHelpGetName,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get role',
|
||||
description: l10n.repeater_cliHelpGetRole,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get public.key',
|
||||
description: l10n.repeater_cliHelpGetPublicKey,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get prv.key',
|
||||
description: l10n.repeater_cliHelpGetPrvKey,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get repeat',
|
||||
description: l10n.repeater_cliHelpGetRepeat,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get tx',
|
||||
description: l10n.repeater_cliHelpGetTx,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get freq',
|
||||
description: l10n.repeater_cliHelpGetFreq,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get radio',
|
||||
description: l10n.repeater_cliHelpGetRadio,
|
||||
),
|
||||
_CommandHelpEntry(
|
||||
command: 'get radio.rxgain',
|
||||
description: l10n.repeater_cliHelpGetRadioRxGain,
|
||||
),
|
||||
_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 = [
|
||||
_CommandHelpEntry(command: 'get pwrmgt.support', description: l10n.repeater_cliHelpGetPwrMgtSupport),
|
||||
_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),
|
||||
_CommandHelpEntry(
|
||||
command: 'get pwrmgt.support',
|
||||
description: l10n.repeater_cliHelpGetPwrMgtSupport,
|
||||
),
|
||||
_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 = [
|
||||
_CommandHelpEntry(command: 'sensor get {key}', description: l10n.repeater_cliHelpSensorGet),
|
||||
_CommandHelpEntry(command: 'sensor set {key} {value}', description: l10n.repeater_cliHelpSensorSet),
|
||||
_CommandHelpEntry(command: 'sensor list [start]', description: l10n.repeater_cliHelpSensorList),
|
||||
_CommandHelpEntry(
|
||||
command: 'sensor get {key}',
|
||||
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 = [
|
||||
_CommandHelpEntry(command: 'gps', description: l10n.repeater_cliHelpGps),
|
||||
_CommandHelpEntry(command: 'gps {on|off}', description: l10n.repeater_cliHelpGpsOnOff),
|
||||
_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),
|
||||
_CommandHelpEntry(
|
||||
command: 'gps {on|off}',
|
||||
description: l10n.repeater_cliHelpGpsOnOff,
|
||||
),
|
||||
_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(
|
||||
@@ -720,27 +1072,64 @@ class _RepeaterCliScreenState extends State<RepeaterCliScreen> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(l10n.repeater_commandsListNote, style: const TextStyle(fontSize: 13)),
|
||||
Text(
|
||||
l10n.repeater_commandsListNote,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_general, generalCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_general,
|
||||
generalCommands,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_getCategory, getCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_getCategory,
|
||||
getCommands,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_settingsCategory, settingsCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_settingsCategory,
|
||||
settingsCommands,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_powerMgmt, powerMgmtCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_powerMgmt,
|
||||
powerMgmtCommands,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_sensors, sensorCommands),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_bridge, bridgeCommands),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_logging, loggingCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_logging,
|
||||
loggingCommands,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildHelpSection(context, l10n.repeater_neighborsRepeaterOnly, neighborCommands),
|
||||
_buildHelpSection(
|
||||
context,
|
||||
l10n.repeater_neighborsRepeaterOnly,
|
||||
neighborCommands,
|
||||
),
|
||||
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),
|
||||
_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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
|
||||
),
|
||||
if (note != null) ...[
|
||||
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),
|
||||
...commands.map((entry) => _buildHelpCommandCard(context, entry)),
|
||||
|
||||
@@ -70,9 +70,7 @@ class RepeaterHubScreen extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
repeater.name,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium
|
||||
style: Theme.of(context).textTheme.titleMedium
|
||||
?.copyWith(fontWeight: FontWeight.w700),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -88,9 +86,7 @@ class RepeaterHubScreen extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
repeater.pathLabel(l10n),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(color: scheme.onSurfaceVariant),
|
||||
),
|
||||
if (repeater.hasLocation) ...[
|
||||
@@ -122,7 +118,9 @@ class RepeaterHubScreen extends StatelessWidget {
|
||||
),
|
||||
StatusChip(
|
||||
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 ──────────────────────────────────────────────────────
|
||||
SectionHeader(
|
||||
isAdmin ? l10n.repeater_managementTools : l10n.repeater_guestTools,
|
||||
isAdmin
|
||||
? l10n.repeater_managementTools
|
||||
: l10n.repeater_guestTools,
|
||||
),
|
||||
|
||||
_HubActionTile(
|
||||
@@ -306,9 +306,7 @@ class _HubActionTile extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: accentColor.withValues(alpha: 0.12),
|
||||
borderRadius: BorderRadius.circular(MeshRadii.md),
|
||||
border: Border.all(
|
||||
color: accentColor.withValues(alpha: 0.3),
|
||||
),
|
||||
border: Border.all(color: accentColor.withValues(alpha: 0.3)),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(icon, size: 22, color: accentColor),
|
||||
@@ -336,11 +334,7 @@ class _HubActionTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: scheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1196,9 +1196,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
|
||||
const SizedBox(height: 12),
|
||||
DropdownButtonFormField<int>(
|
||||
initialValue: _bandwidth,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.repeater_bandwidth,
|
||||
),
|
||||
decoration: InputDecoration(labelText: l10n.repeater_bandwidth),
|
||||
items: _bandwidthOptions.map((bw) {
|
||||
return DropdownMenuItem(
|
||||
value: bw,
|
||||
@@ -1478,7 +1476,9 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
|
||||
child: ListTile(
|
||||
title: Text(l10n.repeater_localAdvertInterval),
|
||||
subtitle: Text(
|
||||
l10n.repeater_localAdvertIntervalMinutes(_advertInterval),
|
||||
l10n.repeater_localAdvertIntervalMinutes(
|
||||
_advertInterval,
|
||||
),
|
||||
),
|
||||
trailing: Switch(
|
||||
value: _advertEnable,
|
||||
@@ -1516,7 +1516,9 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
|
||||
min: 60,
|
||||
max: 240,
|
||||
divisions: 18,
|
||||
label: l10n.repeater_localAdvertIntervalMinutes(_advertInterval),
|
||||
label: l10n.repeater_localAdvertIntervalMinutes(
|
||||
_advertInterval,
|
||||
),
|
||||
onChanged: _advertEnable
|
||||
? (value) {
|
||||
setState(() {
|
||||
@@ -2014,9 +2016,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
|
||||
),
|
||||
subtitle: Text(
|
||||
l10n.repeater_rebootRepeaterSubtitle,
|
||||
style: const TextStyle(
|
||||
color: MeshPalette.warnDim,
|
||||
),
|
||||
style: const TextStyle(color: MeshPalette.warnDim),
|
||||
),
|
||||
onTap: () => _confirmAction(
|
||||
l10n.repeater_rebootRepeater,
|
||||
@@ -2027,19 +2027,14 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
|
||||
),
|
||||
// Regenerate identity key - hidden until fully implemented
|
||||
ListTile(
|
||||
leading: const Icon(
|
||||
Icons.delete_forever,
|
||||
color: MeshPalette.alert,
|
||||
),
|
||||
leading: const Icon(Icons.delete_forever, color: MeshPalette.alert),
|
||||
title: Text(
|
||||
l10n.repeater_eraseFileSystem,
|
||||
style: const TextStyle(color: MeshPalette.alert),
|
||||
),
|
||||
subtitle: Text(
|
||||
l10n.repeater_eraseFileSystemSubtitle,
|
||||
style: const TextStyle(
|
||||
color: MeshPalette.warnDim,
|
||||
),
|
||||
style: const TextStyle(color: MeshPalette.warnDim),
|
||||
),
|
||||
onTap: () => _confirmAction(
|
||||
l10n.repeater_eraseFileSystem,
|
||||
|
||||
@@ -605,7 +605,8 @@ class _RepeaterStatusScreenState extends State<RepeaterStatusScreen> {
|
||||
final batteryMv =
|
||||
connector.getRepeaterBatteryMillivolts(widget.repeater.publicKeyHex) ??
|
||||
_batteryMv;
|
||||
if (batteryMv == null) return Theme.of(context).colorScheme.onSurfaceVariant;
|
||||
if (batteryMv == null)
|
||||
return Theme.of(context).colorScheme.onSurfaceVariant;
|
||||
final percent = estimateBatteryPercentFromMillivolts(
|
||||
batteryMv,
|
||||
_batteryChemistry(),
|
||||
@@ -624,12 +625,14 @@ class _RepeaterStatusScreenState extends State<RepeaterStatusScreen> {
|
||||
crossAxisSpacing: 8,
|
||||
childAspectRatio: 2.2,
|
||||
children: items
|
||||
.map((item) => StatTile(
|
||||
icon: item.icon,
|
||||
label: item.label,
|
||||
value: item.value,
|
||||
color: item.color,
|
||||
))
|
||||
.map(
|
||||
(item) => StatTile(
|
||||
icon: item.icon,
|
||||
label: item.label,
|
||||
value: item.value,
|
||||
color: item.color,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -482,30 +482,30 @@ class _ConnectionStatusHeader extends StatelessWidget {
|
||||
|
||||
final (String label, Color color, bool pulse) = switch (connector.state) {
|
||||
MeshCoreConnectionState.scanning => (
|
||||
l10n.scanner_scanning,
|
||||
MeshPalette.blue,
|
||||
true,
|
||||
),
|
||||
l10n.scanner_scanning,
|
||||
MeshPalette.blue,
|
||||
true,
|
||||
),
|
||||
MeshCoreConnectionState.connecting => (
|
||||
l10n.scanner_connecting,
|
||||
MeshPalette.warn,
|
||||
true,
|
||||
),
|
||||
l10n.scanner_connecting,
|
||||
MeshPalette.warn,
|
||||
true,
|
||||
),
|
||||
MeshCoreConnectionState.connected => (
|
||||
l10n.scanner_connectedTo(connector.deviceDisplayName),
|
||||
MeshPalette.signal,
|
||||
false,
|
||||
),
|
||||
l10n.scanner_connectedTo(connector.deviceDisplayName),
|
||||
MeshPalette.signal,
|
||||
false,
|
||||
),
|
||||
MeshCoreConnectionState.disconnecting => (
|
||||
l10n.scanner_disconnecting,
|
||||
MeshPalette.warn,
|
||||
true,
|
||||
),
|
||||
l10n.scanner_disconnecting,
|
||||
MeshPalette.warn,
|
||||
true,
|
||||
),
|
||||
MeshCoreConnectionState.disconnected => (
|
||||
l10n.scanner_notConnected,
|
||||
scheme.onSurfaceVariant,
|
||||
false,
|
||||
),
|
||||
l10n.scanner_notConnected,
|
||||
scheme.onSurfaceVariant,
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
return Padding(
|
||||
@@ -515,11 +515,7 @@ class _ConnectionStatusHeader extends StatelessWidget {
|
||||
child: Align(
|
||||
key: ValueKey(connector.state),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: StatusChip(
|
||||
label: label,
|
||||
color: color,
|
||||
pulse: pulse,
|
||||
),
|
||||
child: StatusChip(label: label, color: color, pulse: pulse),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -196,11 +196,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
),
|
||||
),
|
||||
if (showChevron)
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: scheme.onSurfaceVariant,
|
||||
size: 16,
|
||||
),
|
||||
Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 16),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -694,11 +690,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: scheme.onSurfaceVariant,
|
||||
size: 16,
|
||||
),
|
||||
Icon(Icons.chevron_right, color: scheme.onSurfaceVariant, size: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -220,9 +220,7 @@ class _TcpScreenState extends State<TcpScreen> {
|
||||
|
||||
if (connector.isTcpTransportConnected) {
|
||||
return StatusChip(
|
||||
label: l10n.scanner_connectedTo(
|
||||
connector.activeTcpEndpoint ?? 'TCP',
|
||||
),
|
||||
label: l10n.scanner_connectedTo(connector.activeTcpEndpoint ?? 'TCP'),
|
||||
color: MeshPalette.signal,
|
||||
);
|
||||
} else if (connector.state == MeshCoreConnectionState.connecting &&
|
||||
|
||||
@@ -604,66 +604,68 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_buildAutoRefreshNumberField(
|
||||
controller: _autoRefreshIntervalController,
|
||||
label: l10n.common_interval,
|
||||
min: _autoRefreshMinIntervalSeconds,
|
||||
max: _autoRefreshMaxIntervalSeconds,
|
||||
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,
|
||||
),
|
||||
controller: _autoRefreshIntervalController,
|
||||
label: l10n.common_interval,
|
||||
min: _autoRefreshMinIntervalSeconds,
|
||||
max: _autoRefreshMaxIntervalSeconds,
|
||||
fallback: _autoRefreshIntervalSeconds,
|
||||
),
|
||||
],
|
||||
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,
|
||||
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),
|
||||
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),
|
||||
Text(
|
||||
value,
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 13,
|
||||
color: scheme.onSurface,
|
||||
),
|
||||
style: MeshTheme.mono(fontSize: 13, color: scheme.onSurface),
|
||||
textAlign: TextAlign.end,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -108,9 +108,7 @@ class _UsbScreenState extends State<UsbScreen> {
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Align(
|
||||
key: ValueKey(
|
||||
'${connector.state}_$_isLoadingPorts',
|
||||
),
|
||||
key: ValueKey('${connector.state}_$_isLoadingPorts'),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: _buildStatusChip(context, connector),
|
||||
),
|
||||
@@ -230,17 +228,11 @@ class _UsbScreenState extends State<UsbScreen> {
|
||||
final l10n = context.l10n;
|
||||
|
||||
if (_isLoadingPorts) {
|
||||
return EmptyState(
|
||||
icon: Icons.usb,
|
||||
title: l10n.usbStatus_searching,
|
||||
);
|
||||
return EmptyState(icon: Icons.usb, title: l10n.usbStatus_searching);
|
||||
}
|
||||
|
||||
if (_ports.isEmpty) {
|
||||
return EmptyState(
|
||||
icon: Icons.usb,
|
||||
title: l10n.usbScreenEmptyState,
|
||||
);
|
||||
return EmptyState(icon: Icons.usb, title: l10n.usbScreenEmptyState);
|
||||
}
|
||||
|
||||
final isConnecting =
|
||||
|
||||
@@ -44,7 +44,8 @@ class RetryServiceConfig {
|
||||
int messageBytes, {
|
||||
String? contactKey,
|
||||
int? deviceTimeoutMs,
|
||||
})? calculateTimeout;
|
||||
})?
|
||||
calculateTimeout;
|
||||
final Uint8List? Function()? getSelfPublicKey;
|
||||
final String Function(Contact, String)? prepareContactOutboundText;
|
||||
final AppSettingsService? appSettingsService;
|
||||
@@ -436,8 +437,7 @@ class MessageRetryService extends ChangeNotifier {
|
||||
final outboundTextForTimeout =
|
||||
config.prepareContactOutboundText?.call(contact, message.text) ??
|
||||
message.text;
|
||||
final messageBytesForTimeout =
|
||||
utf8.encode(outboundTextForTimeout).length;
|
||||
final messageBytesForTimeout = utf8.encode(outboundTextForTimeout).length;
|
||||
|
||||
int actualTimeout = timeoutMs;
|
||||
if (config.calculateTimeout != null) {
|
||||
@@ -704,13 +704,11 @@ class MessageRetryService extends ChangeNotifier {
|
||||
tripTimeMs > 0 &&
|
||||
message.pathLength != null) {
|
||||
final outboundTextForObserved =
|
||||
config!.prepareContactOutboundText?.call(
|
||||
contact,
|
||||
message.text,
|
||||
) ??
|
||||
config!.prepareContactOutboundText?.call(contact, message.text) ??
|
||||
message.text;
|
||||
final messageBytesForObserved =
|
||||
utf8.encode(outboundTextForObserved).length;
|
||||
final messageBytesForObserved = utf8
|
||||
.encode(outboundTextForObserved)
|
||||
.length;
|
||||
config.onDeliveryObserved!(
|
||||
contact.publicKeyHex,
|
||||
message.pathLength!,
|
||||
|
||||
@@ -30,7 +30,9 @@ class DeviceTile extends StatelessWidget {
|
||||
final name = device.platformName.isNotEmpty
|
||||
? device.platformName
|
||||
: 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 scheme = Theme.of(context).colorScheme;
|
||||
|
||||
@@ -55,11 +57,7 @@ class DeviceTile extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
AvatarCircle(
|
||||
name: displayName,
|
||||
size: 42,
|
||||
icon: Icons.router,
|
||||
),
|
||||
AvatarCircle(name: displayName, size: 42, icon: Icons.router),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
@@ -107,10 +105,7 @@ class DeviceTile extends StatelessWidget {
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
'$rssi dBm',
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 10,
|
||||
color: signalUi.color,
|
||||
),
|
||||
style: MeshTheme.mono(fontSize: 10, color: signalUi.color),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -60,10 +60,7 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Switch(
|
||||
value: widget.value,
|
||||
onChanged: widget.onChanged,
|
||||
),
|
||||
Switch(value: widget.value, onChanged: widget.onChanged),
|
||||
if (widget.hasRefreshing) ...[
|
||||
const SizedBox(width: 4),
|
||||
widget.isRefreshing
|
||||
|
||||
@@ -29,10 +29,7 @@ class JumpToBottomButton extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: scheme.surfaceContainerHigh.withValues(alpha: 0.92),
|
||||
border: Border.all(
|
||||
color: scheme.outlineVariant,
|
||||
width: 1,
|
||||
),
|
||||
border: Border.all(color: scheme.outlineVariant, width: 1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.18),
|
||||
|
||||
@@ -350,7 +350,9 @@ class RouteChip extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
final label = isDirect
|
||||
? (hops == null || hops == 0 ? 'DIRECT' : '$hops HOP${hops == 1 ? '' : 'S'}')
|
||||
? (hops == null || hops == 0
|
||||
? 'DIRECT'
|
||||
: '$hops HOP${hops == 1 ? '' : 'S'}')
|
||||
: 'FLOOD';
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
@@ -536,9 +538,7 @@ Future<T?> showMeshSheet<T>(
|
||||
useSafeArea: true,
|
||||
showDragHandle: false,
|
||||
builder: (context) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.viewInsetsOf(context).bottom,
|
||||
),
|
||||
padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom),
|
||||
child: builder(context),
|
||||
),
|
||||
);
|
||||
@@ -574,10 +574,7 @@ class ErrorRetryCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
if (onRetry != null)
|
||||
TextButton(
|
||||
onPressed: onRetry,
|
||||
child: Text(retryLabel ?? 'Retry'),
|
||||
),
|
||||
TextButton(onPressed: onRetry, child: Text(retryLabel ?? 'Retry')),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -610,10 +607,7 @@ class _ListEntranceState extends State<ListEntrance>
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 280),
|
||||
);
|
||||
_curve = CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
_curve = CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic);
|
||||
final delay = Duration(milliseconds: 24 * widget.index.clamp(0, 12));
|
||||
Future.delayed(delay, () {
|
||||
if (mounted) _controller.forward();
|
||||
|
||||
@@ -72,11 +72,7 @@ class _MessageStatusIconState extends State<MessageStatusIcon>
|
||||
if (widget.isFailed) {
|
||||
return Semantics(
|
||||
label: l10n.messageStatus_failed,
|
||||
child: Icon(
|
||||
Icons.cancel,
|
||||
size: size,
|
||||
color: colorScheme.error,
|
||||
),
|
||||
child: Icon(Icons.cancel, size: size, color: colorScheme.error),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,10 +160,7 @@ List<Polyline> buildPacketTrailPolylines(
|
||||
}
|
||||
|
||||
/// The moving packet dot and the pulse ring at the hop it just reached.
|
||||
List<Marker> buildPacketMarkers(
|
||||
PathPlaybackController playback,
|
||||
Color color,
|
||||
) {
|
||||
List<Marker> buildPacketMarkers(PathPlaybackController playback, Color color) {
|
||||
if (!playback.started || !playback.hasPath) return const [];
|
||||
final markers = <Marker>[];
|
||||
|
||||
@@ -412,7 +409,9 @@ class PathAnimationControls extends StatelessWidget {
|
||||
),
|
||||
controlButton(
|
||||
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,
|
||||
),
|
||||
controlButton(
|
||||
@@ -635,7 +634,10 @@ class PathSummaryList extends StatelessWidget {
|
||||
parts.join(' · '),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: MeshTheme.mono(fontSize: 10.5, color: MeshPalette.ink3),
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 10.5,
|
||||
color: MeshPalette.ink3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -332,19 +332,12 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.error,
|
||||
size: 18,
|
||||
color: scheme.error,
|
||||
),
|
||||
Icon(Icons.error, size: 18, color: scheme.error),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
_loginError!,
|
||||
style: TextStyle(
|
||||
color: scheme.error,
|
||||
fontSize: 13,
|
||||
),
|
||||
style: TextStyle(color: scheme.error, fontSize: 13),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -435,9 +428,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
Icon(
|
||||
Icons.auto_mode,
|
||||
size: 20,
|
||||
color: !isFloodMode
|
||||
? scheme.primary
|
||||
: null,
|
||||
color: !isFloodMode ? scheme.primary : null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
@@ -458,9 +449,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
Icon(
|
||||
Icons.waves,
|
||||
size: 20,
|
||||
color: isFloodMode
|
||||
? scheme.primary
|
||||
: null,
|
||||
color: isFloodMode ? scheme.primary : null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
|
||||
@@ -364,9 +364,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
Icon(
|
||||
Icons.auto_mode,
|
||||
size: 20,
|
||||
color: !isFloodMode
|
||||
? scheme.primary
|
||||
: null,
|
||||
color: !isFloodMode ? scheme.primary : null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
@@ -387,9 +385,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
Icon(
|
||||
Icons.waves,
|
||||
size: 20,
|
||||
color: isFloodMode
|
||||
? scheme.primary
|
||||
: null,
|
||||
color: isFloodMode ? scheme.primary : null,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
|
||||
@@ -15,10 +15,7 @@ class UnreadDivider extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: color.withValues(alpha: 0.25),
|
||||
),
|
||||
child: Container(height: 1, color: color.withValues(alpha: 0.25)),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
@@ -39,10 +36,7 @@ class UnreadDivider extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: color.withValues(alpha: 0.25),
|
||||
),
|
||||
child: Container(height: 1, color: color.withValues(alpha: 0.25)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user