diff --git a/lib/core/auth/token_validator.dart b/lib/core/auth/token_validator.dart index 0d3ce38..c0afbd1 100644 --- a/lib/core/auth/token_validator.dart +++ b/lib/core/auth/token_validator.dart @@ -15,7 +15,9 @@ class TokenValidator { } // Check if it's an API key format (starts with sk- or similar) - if (token.startsWith('sk-') || token.startsWith('api-') || token.startsWith('key-')) { + if (token.startsWith('sk-') || + token.startsWith('api-') || + token.startsWith('key-')) { // API key format - validate differently if (token.length < 20) { return TokenValidationResult.invalid('API key too short'); diff --git a/lib/core/models/folder.dart b/lib/core/models/folder.dart index 1d5d4f1..6ddd66a 100644 --- a/lib/core/models/folder.dart +++ b/lib/core/models/folder.dart @@ -22,17 +22,23 @@ sealed class Folder with _$Folder { // Extract conversation IDs from items.chats if available final items = json['items'] as Map?; final chats = items?['chats'] as List?; - + // Handle both string IDs and conversation objects - final conversationIds = chats?.map((chat) { - if (chat is String) { - return chat; - } else if (chat is Map) { - return chat['id'] as String? ?? ''; - } - return ''; - }).where((id) => id.isNotEmpty).toList().cast() ?? []; - + final conversationIds = + chats + ?.map((chat) { + if (chat is String) { + return chat; + } else if (chat is Map) { + return chat['id'] as String? ?? ''; + } + return ''; + }) + .where((id) => id.isNotEmpty) + .toList() + .cast() ?? + []; + // Handle Unix timestamp conversion DateTime? parseTimestamp(dynamic timestamp) { if (timestamp == null) return null; @@ -44,7 +50,7 @@ sealed class Folder with _$Folder { } return null; } - + // Create the modified JSON with proper field mapping return Folder( id: json['id'] as String, diff --git a/lib/core/models/tool.dart b/lib/core/models/tool.dart index 09b9db4..1748abd 100644 --- a/lib/core/models/tool.dart +++ b/lib/core/models/tool.dart @@ -23,4 +23,4 @@ sealed class Tool with _$Tool { meta: json['meta'] as Map?, ); } -} \ No newline at end of file +} diff --git a/lib/core/services/input_validation_service.dart b/lib/core/services/input_validation_service.dart index 4444fe1..5b9d331 100644 --- a/lib/core/services/input_validation_service.dart +++ b/lib/core/services/input_validation_service.dart @@ -43,12 +43,12 @@ class InputValidationService { try { final uri = Uri.parse(urlToValidate); - + // Validate scheme if (!uri.hasScheme || (uri.scheme != 'http' && uri.scheme != 'https')) { return 'Use http:// or https:// only'; } - + // Validate host if (!uri.hasAuthority || uri.host.isEmpty) { return 'Please enter a server address (e.g., 192.168.1.10:3000)'; @@ -65,7 +65,6 @@ class InputValidationService { if (_isIPAddress(uri.host) && !_isValidIPAddress(uri.host)) { return 'Invalid IP address format (use 192.168.1.10)'; } - } catch (e) { return 'Invalid server address format'; } @@ -82,7 +81,7 @@ class InputValidationService { static bool _isValidIPAddress(String ip) { final parts = ip.split('.'); if (parts.length != 4) return false; - + for (final part in parts) { final num = int.tryParse(part); if (num == null || num < 0 || num > 255) return false; diff --git a/lib/core/services/optimized_storage_service.dart b/lib/core/services/optimized_storage_service.dart index 8727f0e..415a0aa 100644 --- a/lib/core/services/optimized_storage_service.dart +++ b/lib/core/services/optimized_storage_service.dart @@ -16,7 +16,9 @@ class OptimizedStorageService { required FlutterSecureStorage secureStorage, required SharedPreferences prefs, }) : _prefs = prefs, - _secureCredentialStorage = SecureCredentialStorage(instance: secureStorage); + _secureCredentialStorage = SecureCredentialStorage( + instance: secureStorage, + ); // Optimized key names with versioning static const String _authTokenKey = 'auth_token_v3'; diff --git a/lib/core/services/persistent_streaming_service.dart b/lib/core/services/persistent_streaming_service.dart index 11f716b..ee32261 100644 --- a/lib/core/services/persistent_streaming_service.dart +++ b/lib/core/services/persistent_streaming_service.dart @@ -74,7 +74,9 @@ class PersistentStreamingService with WidgetsBindingObserver { _connectivitySubscription?.cancel(); _connectivityService = service; - _connectivitySubscription = service.isConnected.listen(_handleConnectivityChange); + _connectivitySubscription = service.isConnected.listen( + _handleConnectivityChange, + ); } void _handleConnectivityChange(bool connected) { diff --git a/lib/core/services/platform_service.dart b/lib/core/services/platform_service.dart index 56ac3dd..5e03970 100644 --- a/lib/core/services/platform_service.dart +++ b/lib/core/services/platform_service.dart @@ -336,10 +336,12 @@ class PlatformService { // on Android 15+. Only control icon brightness; colors come from theme + EdgeToEdge. SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( - statusBarIconBrightness: - isDarkContent ? Brightness.dark : Brightness.light, - systemNavigationBarIconBrightness: - isDarkContent ? Brightness.dark : Brightness.light, + statusBarIconBrightness: isDarkContent + ? Brightness.dark + : Brightness.light, + systemNavigationBarIconBrightness: isDarkContent + ? Brightness.dark + : Brightness.light, // Do NOT set status/navigation bar colors on Android. ), ); diff --git a/lib/core/services/secure_credential_storage.dart b/lib/core/services/secure_credential_storage.dart index 8536653..54ed77f 100644 --- a/lib/core/services/secure_credential_storage.dart +++ b/lib/core/services/secure_credential_storage.dart @@ -9,10 +9,12 @@ class SecureCredentialStorage { late final FlutterSecureStorage _secureStorage; SecureCredentialStorage({FlutterSecureStorage? instance}) { - _secureStorage = instance ?? FlutterSecureStorage( - aOptions: _getAndroidOptions(), - iOptions: _getIOSOptions(), - ); + _secureStorage = + instance ?? + FlutterSecureStorage( + aOptions: _getAndroidOptions(), + iOptions: _getIOSOptions(), + ); } static const String _credentialsKey = 'user_credentials_v2'; diff --git a/lib/core/services/storage_service.dart b/lib/core/services/storage_service.dart index b0bff3e..954f800 100644 --- a/lib/core/services/storage_service.dart +++ b/lib/core/services/storage_service.dart @@ -16,7 +16,9 @@ class StorageService { required SharedPreferences prefs, }) : _secureStorage = secureStorage, _prefs = prefs, - _secureCredentialStorage = SecureCredentialStorage(instance: secureStorage); + _secureCredentialStorage = SecureCredentialStorage( + instance: secureStorage, + ); // Secure storage keys static const String _authTokenKey = 'auth_token'; diff --git a/lib/core/services/tools_service.dart b/lib/core/services/tools_service.dart index f66d25b..c3e4211 100644 --- a/lib/core/services/tools_service.dart +++ b/lib/core/services/tools_service.dart @@ -26,4 +26,4 @@ final toolsServiceProvider = Provider((ref) { final apiService = ref.watch(apiServiceProvider); if (apiService == null) return null; return ToolsService(apiService); -}); \ No newline at end of file +}); diff --git a/lib/core/utils/inactivity_watchdog.dart b/lib/core/utils/inactivity_watchdog.dart index 00453ac..8d0f71c 100644 --- a/lib/core/utils/inactivity_watchdog.dart +++ b/lib/core/utils/inactivity_watchdog.dart @@ -10,8 +10,8 @@ class InactivityWatchdog { required Duration window, required this.onTimeout, Duration? absoluteCap, - }) : _window = window, - _absoluteCap = absoluteCap; + }) : _window = window, + _absoluteCap = absoluteCap; final void Function() onTimeout; @@ -80,4 +80,3 @@ class InactivityWatchdog { } catch (_) {} } } - diff --git a/lib/features/chat/services/reviewer_mode_service.dart b/lib/features/chat/services/reviewer_mode_service.dart index c9cf583..bd51c86 100644 --- a/lib/features/chat/services/reviewer_mode_service.dart +++ b/lib/features/chat/services/reviewer_mode_service.dart @@ -44,35 +44,36 @@ class ReviewerModeService { bool isVoiceInput = false, }) { final lowerMessage = userMessage.toLowerCase(); - + // Determine response category String category = 'general'; - - if (lowerMessage.contains('hello') || - lowerMessage.contains('hi') || + + if (lowerMessage.contains('hello') || + lowerMessage.contains('hi') || lowerMessage.contains('hey') || lowerMessage.contains('greet')) { category = 'greeting'; - } else if (lowerMessage.contains('code') || - lowerMessage.contains('program') || - lowerMessage.contains('function') || - lowerMessage.contains('debug')) { + } else if (lowerMessage.contains('code') || + lowerMessage.contains('program') || + lowerMessage.contains('function') || + lowerMessage.contains('debug')) { category = 'code'; - } else if (lowerMessage.contains('feature') || - lowerMessage.contains('capability') || - lowerMessage.contains('what can') || - lowerMessage.contains('help')) { + } else if (lowerMessage.contains('feature') || + lowerMessage.contains('capability') || + lowerMessage.contains('what can') || + lowerMessage.contains('help')) { category = 'features'; } else if (filename != null) { category = 'attachments'; } else if (isVoiceInput) { category = 'voice'; } - + // Get responses for category - final responses = _cannedResponses[category] ?? _cannedResponses['general']!; + final responses = + _cannedResponses[category] ?? _cannedResponses['general']!; final response = responses[_random.nextInt(responses.length)]; - + // Replace placeholders return response .replaceAll('{query}', userMessage) @@ -92,4 +93,4 @@ class ReviewerModeService { isVoiceInput: isVoiceInput, ); } -} \ No newline at end of file +} diff --git a/lib/features/chat/views/chat_page_helpers.dart b/lib/features/chat/views/chat_page_helpers.dart index a335c6e..bf3637b 100644 --- a/lib/features/chat/views/chat_page_helpers.dart +++ b/lib/features/chat/views/chat_page_helpers.dart @@ -65,4 +65,3 @@ class _PressableScaleState extends State ); } } - diff --git a/lib/shared/services/brand_service.dart b/lib/shared/services/brand_service.dart index 7baadf8..e440161 100644 --- a/lib/shared/services/brand_service.dart +++ b/lib/shared/services/brand_service.dart @@ -229,7 +229,7 @@ class BrandService { return AppBar( title: Text( title, - style: context != null + style: context != null ? context.conduitTheme.headingSmall?.copyWith( color: context.conduitTheme.textPrimary, fontWeight: FontWeight.w600, diff --git a/lib/shared/services/tasks/outbound_task.dart b/lib/shared/services/tasks/outbound_task.dart index cf77ffe..fa2dc0a 100644 --- a/lib/shared/services/tasks/outbound_task.dart +++ b/lib/shared/services/tasks/outbound_task.dart @@ -3,13 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'outbound_task.freezed.dart'; part 'outbound_task.g.dart'; -enum TaskStatus { - queued, - running, - succeeded, - failed, - cancelled, -} +enum TaskStatus { queued, running, succeeded, failed, cancelled } @freezed abstract class OutboundTask with _$OutboundTask { @@ -74,7 +68,6 @@ abstract class OutboundTask with _$OutboundTask { String? error, }) = GenerateImageTask; - const factory OutboundTask.generateTitle({ required String id, required String conversationId, @@ -106,16 +99,16 @@ abstract class OutboundTask with _$OutboundTask { // Provide a unified nullable conversationId across variants String? get maybeConversationId => map( - sendTextMessage: (t) => t.conversationId, - uploadMedia: (t) => t.conversationId, - executeToolCall: (t) => t.conversationId, - generateImage: (t) => t.conversationId, - generateTitle: (t) => t.conversationId, - imageToDataUrl: (t) => t.conversationId, - ); + sendTextMessage: (t) => t.conversationId, + uploadMedia: (t) => t.conversationId, + executeToolCall: (t) => t.conversationId, + generateImage: (t) => t.conversationId, + generateTitle: (t) => t.conversationId, + imageToDataUrl: (t) => t.conversationId, + ); String get threadKey => (maybeConversationId == null || maybeConversationId!.isEmpty) - ? 'new' - : maybeConversationId!; + ? 'new' + : maybeConversationId!; } diff --git a/lib/shared/theme/theme_extensions.dart b/lib/shared/theme/theme_extensions.dart index 2a3c5d6..ef16045 100644 --- a/lib/shared/theme/theme_extensions.dart +++ b/lib/shared/theme/theme_extensions.dart @@ -751,10 +751,6 @@ class ConduitThemeExtension extends ThemeExtension { fontFamily: AppTypography.monospaceFontFamily, ), ); - - - - } /// Extension method to easily access Conduit theme from BuildContext diff --git a/lib/shared/widgets/chat_action_button.dart b/lib/shared/widgets/chat_action_button.dart index b3829d7..f60dce3 100644 --- a/lib/shared/widgets/chat_action_button.dart +++ b/lib/shared/widgets/chat_action_button.dart @@ -31,7 +31,8 @@ class _ChatActionButtonState extends ConsumerState { Widget build(BuildContext context) { final theme = context.conduitTheme; final hapticEnabled = ref.read(hapticEnabledProvider); - final radius = widget.borderRadius ?? BorderRadius.circular(AppBorderRadius.lg); + final radius = + widget.borderRadius ?? BorderRadius.circular(AppBorderRadius.lg); final overlay = theme.buttonPrimary.withValues(alpha: 0.08); return Tooltip( @@ -100,4 +101,3 @@ class _ChatActionButtonState extends ConsumerState { ); } } - diff --git a/lib/shared/widgets/conduit_components.dart b/lib/shared/widgets/conduit_components.dart index ede4ea2..df9b2c4 100644 --- a/lib/shared/widgets/conduit_components.dart +++ b/lib/shared/widgets/conduit_components.dart @@ -101,7 +101,8 @@ class ConduitButton extends ConsumerWidget { ), child: isLoading ? Semantics( - label: AppLocalizations.of(context)?.loadingContent ?? 'Loading', + label: + AppLocalizations.of(context)?.loadingContent ?? 'Loading', excludeSemantics: true, child: SizedBox( width: IconSize.small, @@ -206,7 +207,10 @@ class ConduitInput extends StatelessWidget { SizedBox(height: Spacing.sm), ], Semantics( - label: semanticLabel ?? label ?? (AppLocalizations.of(context)?.inputField ?? 'Input field'), + label: + semanticLabel ?? + label ?? + (AppLocalizations.of(context)?.inputField ?? 'Input field'), textField: true, child: TextField( controller: controller, @@ -784,7 +788,10 @@ class AccessibleFormField extends StatelessWidget { SizedBox(height: isCompact ? Spacing.xs : Spacing.sm), ], Semantics( - label: semanticLabel ?? label ?? (AppLocalizations.of(context)?.inputField ?? 'Input field'), + label: + semanticLabel ?? + label ?? + (AppLocalizations.of(context)?.inputField ?? 'Input field'), textField: true, child: TextFormField( controller: controller, diff --git a/lib/shared/widgets/loading_states.dart b/lib/shared/widgets/loading_states.dart index a2bec18..7ef6d7c 100644 --- a/lib/shared/widgets/loading_states.dart +++ b/lib/shared/widgets/loading_states.dart @@ -348,8 +348,13 @@ class LoadingStateWrapper extends StatelessWidget { return asyncValue.when( data: builder, loading: () => showLoadingOverlay - ? ConduitLoading.overlay(message: AppLocalizations.of(context)!.loadingContent) - : loadingWidget ?? ConduitLoading.primary(message: AppLocalizations.of(context)!.loadingContent), + ? ConduitLoading.overlay( + message: AppLocalizations.of(context)!.loadingContent, + ) + : loadingWidget ?? + ConduitLoading.primary( + message: AppLocalizations.of(context)!.loadingContent, + ), error: (error, stackTrace) { if (errorBuilder != null) { return errorBuilder!(error, stackTrace); diff --git a/lib/shared/widgets/markdown/markdown_config.dart b/lib/shared/widgets/markdown/markdown_config.dart index 0496ceb..9da1e91 100644 --- a/lib/shared/widgets/markdown/markdown_config.dart +++ b/lib/shared/widgets/markdown/markdown_config.dart @@ -155,7 +155,11 @@ class ConduitMarkdownConfig { ); } - static Widget _buildBase64Image(String dataUrl, BuildContext context, ConduitThemeExtension theme) { + static Widget _buildBase64Image( + String dataUrl, + BuildContext context, + ConduitThemeExtension theme, + ) { try { // Extract base64 part from data URL final commaIndex = dataUrl.indexOf(','); diff --git a/lib/shared/widgets/markdown/streaming_markdown_widget.dart b/lib/shared/widgets/markdown/streaming_markdown_widget.dart index f4b01c2..4f5525e 100644 --- a/lib/shared/widgets/markdown/streaming_markdown_widget.dart +++ b/lib/shared/widgets/markdown/streaming_markdown_widget.dart @@ -20,7 +20,8 @@ class StreamingMarkdownWidget extends StatefulWidget { }); @override - State createState() => _StreamingMarkdownWidgetState(); + State createState() => + _StreamingMarkdownWidgetState(); } class _StreamingMarkdownWidgetState extends State { @@ -59,38 +60,38 @@ class _StreamingMarkdownWidgetState extends State { if (fenceCount % 2 != 0) { content += '\n```'; } - + // Fix incomplete bold/italic markers final boldCount = RegExp(r'\*\*').allMatches(content).length; if (boldCount % 2 != 0) { content += '**'; } - + final italicCount = RegExp(r'(? closeBrackets) { content += ']' * (openBrackets - closeBrackets); } - + final openParens = '('.allMatches(content).length; final closeParens = ')'.allMatches(content).length; if (openParens > closeParens) { content += ')' * (openParens - closeParens); } - + return content; } @override void didUpdateWidget(StreamingMarkdownWidget oldWidget) { super.didUpdateWidget(oldWidget); - + // Handle stream changes if (widget.contentStream != oldWidget.contentStream) { _streamSubscription?.cancel(); @@ -98,7 +99,7 @@ class _StreamingMarkdownWidgetState extends State { _streamSubscription = widget.contentStream!.listen(_handleChunk); } } - + // Handle static content changes if (widget.staticContent != oldWidget.staticContent) { setState(() { @@ -182,9 +183,7 @@ class MarkdownWithLoading extends StatelessWidget { if (isLoading && (content == null || content!.isEmpty)) { return Container( padding: padding ?? const EdgeInsets.all(16), - child: const Center( - child: CircularProgressIndicator(), - ), + child: const Center(child: CircularProgressIndicator()), ); } @@ -194,4 +193,4 @@ class MarkdownWithLoading extends StatelessWidget { padding: padding, ); } -} \ No newline at end of file +} diff --git a/lib/shared/widgets/middle_ellipsis_text.dart b/lib/shared/widgets/middle_ellipsis_text.dart index 28dfb71..9d353fd 100644 --- a/lib/shared/widgets/middle_ellipsis_text.dart +++ b/lib/shared/widgets/middle_ellipsis_text.dart @@ -22,8 +22,9 @@ class MiddleEllipsisText extends StatelessWidget { Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { - final TextStyle effectiveStyle = - DefaultTextStyle.of(context).style.merge(style); + final TextStyle effectiveStyle = DefaultTextStyle.of( + context, + ).style.merge(style); final TextDirection direction = Directionality.of(context); final double maxWidth = constraints.maxWidth; @@ -74,8 +75,10 @@ class MiddleEllipsisText extends StatelessWidget { ? '' : text.substring(text.length - rightCount); - final trialSpan = - TextSpan(text: '$start$ellipsis$end', style: effectiveStyle); + final trialSpan = TextSpan( + text: '$start$ellipsis$end', + style: effectiveStyle, + ); final trialPainter = TextPainter( text: trialSpan, textDirection: direction, @@ -116,4 +119,3 @@ class MiddleEllipsisText extends StatelessWidget { ); } } - diff --git a/lib/shared/widgets/optimized_list.dart b/lib/shared/widgets/optimized_list.dart index c680ec7..6635f68 100644 --- a/lib/shared/widgets/optimized_list.dart +++ b/lib/shared/widgets/optimized_list.dart @@ -130,7 +130,9 @@ class _OptimizedListState extends ConsumerState> { return widget.emptyWidget ?? ImprovedEmptyState( title: AppLocalizations.of(context)!.noItems, - subtitle: widget.emptyMessage ?? AppLocalizations.of(context)!.noItemsToDisplay, + subtitle: + widget.emptyMessage ?? + AppLocalizations.of(context)!.noItemsToDisplay, icon: Icons.inbox_outlined, ); } @@ -138,7 +140,8 @@ class _OptimizedListState extends ConsumerState> { // Build the list Widget listWidget; - final ScrollPhysics effectivePhysics = widget.physics ?? + final ScrollPhysics effectivePhysics = + widget.physics ?? (widget.onRefresh != null ? const AlwaysScrollableScrollPhysics() : const ClampingScrollPhysics()); @@ -276,14 +279,16 @@ class OptimizedSliverList extends ConsumerWidget { return SliverToBoxAdapter( child: emptyWidget ?? - Builder(builder: (context) { - final l10n = AppLocalizations.of(context)!; - return ImprovedEmptyState( - title: l10n.noItems, - subtitle: emptyMessage ?? l10n.noItemsToDisplay, - icon: Icons.inbox_outlined, - ); - }), + Builder( + builder: (context) { + final l10n = AppLocalizations.of(context)!; + return ImprovedEmptyState( + title: l10n.noItems, + subtitle: emptyMessage ?? l10n.noItemsToDisplay, + icon: Icons.inbox_outlined, + ); + }, + ), ); } diff --git a/lib/shared/widgets/sheet_handle.dart b/lib/shared/widgets/sheet_handle.dart index ecd973c..15d3478 100644 --- a/lib/shared/widgets/sheet_handle.dart +++ b/lib/shared/widgets/sheet_handle.dart @@ -9,15 +9,18 @@ class SheetHandle extends StatelessWidget { Widget build(BuildContext context) { return Center( child: Container( - margin: margin ?? const EdgeInsets.only(top: Spacing.sm, bottom: Spacing.md), + margin: + margin ?? + const EdgeInsets.only(top: Spacing.sm, bottom: Spacing.md), width: 40, height: 4, decoration: BoxDecoration( - color: context.conduitTheme.textPrimary.withValues(alpha: Alpha.medium), + color: context.conduitTheme.textPrimary.withValues( + alpha: Alpha.medium, + ), borderRadius: BorderRadius.circular(AppBorderRadius.xs), ), ), ); } } - diff --git a/lib/shared/widgets/themed_dialogs.dart b/lib/shared/widgets/themed_dialogs.dart index c7e8c45..6431a52 100644 --- a/lib/shared/widgets/themed_dialogs.dart +++ b/lib/shared/widgets/themed_dialogs.dart @@ -145,8 +145,10 @@ class ThemedDialogs { ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(AppBorderRadius.md), - borderSide: - BorderSide(color: theme.buttonPrimary, width: 1), + borderSide: BorderSide( + color: theme.buttonPrimary, + width: 1, + ), ), contentPadding: const EdgeInsets.symmetric( horizontal: Spacing.md, @@ -155,8 +157,8 @@ class ThemedDialogs { ), onSubmitted: (v) { final trimmed = v.trim(); - final unchanged = (initialValue != null && - trimmed == initialValue.trim()); + final unchanged = + (initialValue != null && trimmed == initialValue.trim()); if (trimmed.isEmpty || unchanged) return; Navigator.of(ctx).pop(trimmed); }, diff --git a/tool/validate_arb_locales.dart b/tool/validate_arb_locales.dart index 211c7dc..9ebc25a 100644 --- a/tool/validate_arb_locales.dart +++ b/tool/validate_arb_locales.dart @@ -56,12 +56,16 @@ Future main(List args) async { if (trPh == null) { // If string exists but no meta placeholders, warn only. if (keys.contains(k) && basePh.isNotEmpty) { - warnings.add('[${f.path}] Key "$k" missing @meta placeholders; base has ${basePh.toList()..sort()}'); + warnings.add( + '[${f.path}] Key "$k" missing @meta placeholders; base has ${basePh.toList()..sort()}', + ); } continue; } if (basePh.length != trPh.length || !basePh.containsAll(trPh)) { - warnings.add('[${f.path}] Placeholder mismatch for "$k": expected ${basePh.toList()..sort()}, got ${trPh.toList()..sort()}'); + warnings.add( + '[${f.path}] Placeholder mismatch for "$k": expected ${basePh.toList()..sort()}, got ${trPh.toList()..sort()}', + ); } } } @@ -96,9 +100,7 @@ Map _readJson(File f) { } Set _nonMetaKeys(Map m) { - return m.keys - .where((k) => !k.startsWith('@') && k != '@@locale') - .toSet(); + return m.keys.where((k) => !k.startsWith('@') && k != '@@locale').toSet(); } Map> _placeholdersMap(Map m) { diff --git a/tool/verify_arb_descriptions.dart b/tool/verify_arb_descriptions.dart index 83ac6f6..f6d721c 100644 --- a/tool/verify_arb_descriptions.dart +++ b/tool/verify_arb_descriptions.dart @@ -42,7 +42,9 @@ Future main() async { } if (missingMeta.isEmpty && missingDescription.isEmpty) { - stdout.writeln('ARB descriptions check passed: all keys have @meta.description.'); + stdout.writeln( + 'ARB descriptions check passed: all keys have @meta.description.', + ); return; } @@ -53,11 +55,12 @@ Future main() async { } } if (missingDescription.isNotEmpty) { - stderr.writeln('Missing description in @meta for keys (${missingDescription.length}):'); + stderr.writeln( + 'Missing description in @meta for keys (${missingDescription.length}):', + ); for (final k in missingDescription) { stderr.writeln(' - $k'); } } exit(1); } -