-
Notifications
You must be signed in to change notification settings - Fork 13
Added paste npub cta in profile search sheet #642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added paste npub cta in profile search sheet #642
Conversation
WalkthroughAdds a paste-from-clipboard helper and tests; wires paste CTAs into New Chat bottom sheet, New Group Chat sheet, and Login screen; auto-strips whitespace for inputs starting with Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as "NewChat / NewGroupChat / LoginScreen"
participant Clipboard as "System Clipboard"
participant Toast as "ToastService"
User->>UI: Tap paste CTA
UI->>Clipboard: Clipboard.getData(Clipboard.kTextPlain)
alt clipboard has text
Clipboard-->>UI: text
UI->>UI: if text.startswith("npub") then remove whitespace\nupdate controller.text & move caret to end
UI->>Toast: show success toast
UI-->>User: pasted text visible in input
else empty/null
Clipboard-->>UI: empty/null
UI->>Toast: show info toast
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
CHANGELOG.md (1)
15-15: Tighten wording and casing for consistency with sheet title.Prefer: “Start New Chat: add Paste from clipboard CTA in the search field.”
Apply this diff:
-- Paste from clipboard functionality (cta) in new chat bottom sheet. +- Start New Chat: add Paste from clipboard CTA in the search field.lib/ui/contact_list/new_chat_bottom_sheet.dart (2)
36-36: Localize the new title.Use AppLocalizations instead of a hardcoded string.
Apply this diff (adjust to your l10n API):
- title: 'Start New Chat', + title: AppLocalizations.of(context)!.startNewChat,
352-391: Add tooltip/semantics and meet 48×48 tap target for the paste CTA; localize hint.
- Wrap the icon button in Tooltip and bump size to 48 for a11y.
- Localize the hintText.
Apply this diff:
- Expanded( + Expanded( child: WnTextFormField( controller: _searchController, focusNode: _searchFocusNode, size: FieldSize.small, - hintText: 'Search contact or public key...', + hintText: AppLocalizations.of(context)!.searchContactOrPubkeyHint, decoration: InputDecoration( @@ - WnIconButton( - iconPath: AssetsPaths.icPaste, - onTap: _pasteFromClipboard, - padding: 14.w, - size: 44.h, - ), + Tooltip( + message: AppLocalizations.of(context)!.pasteFromClipboard, + child: WnIconButton( + iconPath: AssetsPaths.icPaste, + onTap: _pasteFromClipboard, + padding: 14.w, + size: 48.w, + ), + ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
CHANGELOG.md(1 hunks)lib/ui/contact_list/new_chat_bottom_sheet.dart(7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
📄 CodeRabbit inference engine (.cursor/rules/whitenoise.mdc)
**/*.md: NIPs (Nostr Implementation Possibilities) are numbered likeNIP-XXwhereXXare two capitalized hexadecimal digits, e.g.,NIP-01andNIP-C7.
To read a specific NIP, construct the NIP URL following this template:https://raw.githubusercontent.com/nostr-protocol/nips/refs/heads/master/{nip}.md(replace{nip}in the URL template with the relevant NIP name, e.g.,07for NIP-07, orC7for NIP-C7).
To read the definition of a specific kind, construct a URL following this template:https://nostrbook.dev/kinds/{kind}.md(replace{kind}in the template with the kind number, e.g.,https://nostrbook.dev/kinds/0.mdfor kind 0).
Files:
CHANGELOG.md
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
🧠 Learnings (4)
📚 Learning: 2025-08-08T13:39:00.500Z
Learnt from: CR
PR: parres-hq/whitenoise_flutter#0
File: .cursor/rules/flutter.mdc:0-0
Timestamp: 2025-08-08T13:39:00.500Z
Learning: Applies to **/*.dart : Use Riverpod to manage state. Use StreamProviders to watch for state changes that come from the rust api. See keepAlive if you need to keep the state alive.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-08-23T11:02:28.308Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#527
File: lib/ui/core/ui/wn_avatar.dart:1-6
Timestamp: 2025-08-23T11:02:28.308Z
Learning: In the whitenoise_flutter codebase, flutter_screenutil is re-exported through lib/ui/core/themes/src/app_theme.dart, so files that import app_theme.dart do not need to directly import flutter_screenutil to use .w, .h, .sp extensions.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-01T14:56:50.988Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#568
File: lib/ui/core/ui/wn_image.dart:1-2
Timestamp: 2025-09-01T14:56:50.988Z
Learning: The whitenoise_flutter project does not target web platforms and any future web version would be in a separate repository, so dart:io imports and file system operations are acceptable in this codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-16T06:28:24.611Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#640
File: lib/ui/chat/services/chat_dialog_service.dart:21-25
Timestamp: 2025-09-16T06:28:24.611Z
Learning: In lib/ui/core/ui/wn_bottom_sheet.dart, the WnBottomSheet.show method has barrierDismissible parameter that defaults to false, not true.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (3)
lib/ui/contact_list/new_chat_bottom_sheet.dart (3)
2-2: Clipboard and button imports LGTM.Both are needed for the new paste CTA.
Also applies to: 22-22
392-392: No action.Spacing tweak is fine.
406-406: No action.Spacing tweak is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
lib/ui/contact_list/new_chat_bottom_sheet.dart(8 hunks)lib/ui/contact_list/new_group_chat_sheet.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/ui/contact_list/new_chat_bottom_sheet.dart
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
lib/ui/contact_list/new_group_chat_sheet.dart
🪛 GitHub Actions: CI
lib/ui/contact_list/new_group_chat_sheet.dart
[error] 1-1: Dart format changed this file due to formatting by 'dart format --set-exit-if-changed lib/ integration_test/'. Please run 'dart format' and commit the changes.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (1)
lib/ui/contact_list/new_group_chat_sheet.dart (1)
1-212: Fix CI: run dart format and commit.CI failed with “dart format changed this file…”. Please run: dart format --set-exit-if-changed lib/ integration_test/ and commit the result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
lib/ui/contact_list/new_chat_bottom_sheet.dart (1)
581-582: Compile error:const EdgeInsets.all(13).w.Remove
constand scale the numeric literal.- padding: const EdgeInsets.all(13).w, + padding: EdgeInsets.all(13.w),
🧹 Nitpick comments (7)
lib/utils/clipboard_utils.dart (3)
98-106: Type the callback and hoist logger (avoid per-call allocation).
- Prefer
void Function(String)overFunction(String).- Use a static class logger; remove the local
Logger(...).- static Future<void> pasteWithToast({ - required WidgetRef ref, - required Function(String) onPaste, + static Future<void> pasteWithToast({ + required WidgetRef ref, + required void Function(String) onPaste, @@ - }) async { - final logger = Logger('ClipboardUtils'); + }) async {Add this near other statics in the class (outside the function):
static final Logger _logger = Logger('ClipboardUtils');
122-129: Use class logger; broaden error handling.
- Swap to
_logger.- Optionally add a generic
catchto cover non-Platform exceptions.- } on PlatformException catch (e) { - logger.warning('Clipboard read failed: $e'); + } on PlatformException catch (e) { + _logger.warning('Clipboard read failed: $e'); ref.showErrorToast( errorMessage ?? 'Clipboard unavailable', autoDismiss: true, ); - } + } catch (e) { + _logger.warning('Clipboard read failed (non-platform): $e'); + ref.showErrorToast( + errorMessage ?? 'Clipboard unavailable', + autoDismiss: true, + ); + }
98-129: Localize toast strings.Route messages through
AppLocalizationsinstead of hard-coded English.lib/ui/auth_flow/login_screen.dart (1)
200-206: Set caret to end after paste; simplify handler.Ensure a good UX and avoid redundant
awaitin arrow body.- onTap: - () async => await ClipboardUtils.pasteWithToast( + onTap: () async { + await ClipboardUtils.pasteWithToast( ref: ref, onPaste: (text) { - _keyController.text = text; + _keyController.value = TextEditingValue( + text: text, + selection: TextSelection.collapsed(offset: text.length), + ); }, - ), + ); + },lib/ui/contact_list/new_chat_bottom_sheet.dart (3)
36-36: Localize bottom sheet title.Use
AppLocalizationsinstead of a hard-coded string.- title: 'Start New Chat', + title: AppLocalizations.of(context)!.startNewChat,
76-91: Comment/code mismatch; makenpubcheck case-insensitive.Comment mentions “npub or hex-like,” but code only checks
npub1and case-sensitively.- if (originalText.startsWith('npub1')) { + if (originalText.toLowerCase().startsWith('npub1')) { processedText = originalText.replaceAll(RegExp(r'\s+'), '');If hex handling is out of scope, adjust the comment accordingly.
354-399: Paste handler UX: set caret; prefer block body.Mirror the login screen behavior for consistency.
- WnIconButton( + WnIconButton( iconPath: AssetsPaths.icPaste, - onTap: - () async => await ClipboardUtils.pasteWithToast( - ref: ref, - onPaste: (text) { - _searchController.text = text; - }, - ), + onTap: () async { + await ClipboardUtils.pasteWithToast( + ref: ref, + onPaste: (text) { + _searchController.value = TextEditingValue( + text: text, + selection: TextSelection.collapsed(offset: text.length), + ); + }, + ); + }, padding: 14.w, size: 44.h, ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
lib/ui/auth_flow/login_screen.dart(2 hunks)lib/ui/contact_list/new_chat_bottom_sheet.dart(6 hunks)lib/ui/contact_list/new_group_chat_sheet.dart(1 hunks)lib/utils/clipboard_utils.dart(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/ui/contact_list/new_group_chat_sheet.dart
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
lib/ui/auth_flow/login_screen.dartlib/utils/clipboard_utils.dartlib/ui/contact_list/new_chat_bottom_sheet.dart
🧠 Learnings (8)
📓 Common learnings
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
📚 Learning: 2025-09-07T02:15:31.931Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/src/rust/api/utils.dart:12-16
Timestamp: 2025-09-07T02:15:31.931Z
Learning: The lingering PublicKey references in lib/config/providers/auth_provider.dart, lib/config/providers/group_provider.dart, and rust_builder/cargokit/build_tool/lib/src/options.dart identified during the utils.dart API cleanup were fixed in PR #597 in the whitenoise_flutter codebase.
Applied to files:
lib/ui/auth_flow/login_screen.dartlib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-08-23T11:02:28.308Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#527
File: lib/ui/core/ui/wn_avatar.dart:1-6
Timestamp: 2025-08-23T11:02:28.308Z
Learning: In the whitenoise_flutter codebase, flutter_screenutil is re-exported through lib/ui/core/themes/src/app_theme.dart, so files that import app_theme.dart do not need to directly import flutter_screenutil to use .w, .h, .sp extensions.
Applied to files:
lib/ui/auth_flow/login_screen.dartlib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-08-08T13:39:00.500Z
Learnt from: CR
PR: parres-hq/whitenoise_flutter#0
File: .cursor/rules/flutter.mdc:0-0
Timestamp: 2025-08-08T13:39:00.500Z
Learning: Applies to **/*.dart : Use Riverpod to manage state. Use StreamProviders to watch for state changes that come from the rust api. See keepAlive if you need to keep the state alive.
Applied to files:
lib/ui/auth_flow/login_screen.dart
📚 Learning: 2025-09-07T02:08:09.199Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/domain/models/contact_model.dart:36-41
Timestamp: 2025-09-07T02:08:09.199Z
Learning: The issue of ContactModel.publicKey potentially being set to an empty string when pubkey.toNpub() conversion fails (causing collision/lookup issues) is being addressed in PR #597 in the whitenoise_flutter codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-16T07:24:07.453Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-05T00:08:34.509Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/config/providers/active_account_provider.dart:140-146
Timestamp: 2025-09-05T00:08:34.509Z
Learning: josefinalliende prefers centralizing validation logic (like trimming whitespace) in providers rather than handling it defensively at every consumer site. This approach was applied to activePubkeyProvider in the whitenoise_flutter codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-16T06:28:24.611Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#640
File: lib/ui/chat/services/chat_dialog_service.dart:21-25
Timestamp: 2025-09-16T06:28:24.611Z
Learning: In lib/ui/core/ui/wn_bottom_sheet.dart, the WnBottomSheet.show method has barrierDismissible parameter that defaults to false, not true.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (2)
lib/ui/auth_flow/login_screen.dart (1)
16-16: LGTM: Centralized paste via ClipboardUtils.lib/ui/contact_list/new_chat_bottom_sheet.dart (1)
21-24: LGTM: Imports for paste CTA.
…/github.com/parres-hq/whitenoise_flutter into 477-past-npub-icon-button-in-profile-search
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
lib/ui/contact_list/new_group_chat_sheet.dart (1)
58-76: Don’t mutate the controller; sanitize only for key matching.Updating
_searchController.valuemid-typing is jarring and can break IME/selection. Keep raw trimmed text for name/NIP‑05, use a sanitized variant only when matching keys. Also remove intra‑function blank lines per guidelines. Comment about “hex-like” isn’t implemented.Apply this diff:
void _onSearchChanged() { - final originalText = _searchController.text; - String processedText = originalText; - - // Only remove whitespace if it looks like a public key (starts with npub or is hex-like) - if (originalText.startsWith('npub1')) { - processedText = originalText.replaceAll(RegExp(r'\s+'), ''); - - // Update the controller if we removed whitespace - if (originalText != processedText) { - _searchController.value = _searchController.value.copyWith( - text: processedText, - selection: TextSelection.collapsed(offset: processedText.length), - ); - } - } - - setState(() { - _searchQuery = processedText; - }); + final String text = _searchController.text; + setState(() { + _searchQuery = text.trim(); + }); }
🧹 Nitpick comments (2)
lib/ui/contact_list/new_group_chat_sheet.dart (2)
133-147: Use sanitized “no‑whitespace” variant only for publicKey matching.Precompute
qandkeyQ. This preserves display‑name/NIP‑05 searches with spaces while still handling pastednpub1…with inserted whitespace.- return contactsWithoutCreator - .where( - (contact) => - contact.displayName.toLowerCase().contains( - _searchQuery.toLowerCase(), - ) || - (contact.nip05?.toLowerCase().contains( - _searchQuery.toLowerCase(), - ) ?? - false) || - contact.publicKey.toLowerCase().contains( - _searchQuery.toLowerCase(), - ), - ) - .toList(); + final String q = _searchQuery.toLowerCase(); + final String keyQ = _searchQuery.replaceAll(RegExp(r'\s+'), '').toLowerCase(); + return contactsWithoutCreator + .where( + (contact) => + contact.displayName.toLowerCase().contains(q) || + (contact.nip05?.toLowerCase().contains(q) ?? false) || + contact.publicKey.toLowerCase().contains(keyQ), + ) + .toList();
164-197: Add an accessibility label for the paste button.Improve a11y/UX for screen readers.
- WnIconButton( - iconPath: AssetsPaths.icPaste, - onTap: - () async => await ClipboardUtils.pasteWithToast( - ref: ref, - onPaste: (text) { - _searchController.text = text; - }, - ), - padding: 14.w, - size: 44.h, - ), + Semantics( + button: true, + label: 'Paste', + child: WnIconButton( + iconPath: AssetsPaths.icPaste, + onTap: () async => await ClipboardUtils.pasteWithToast( + ref: ref, + onPaste: (text) { + _searchController.text = text; + }, + ), + padding: 14.w, + size: 44.h, + ), + ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
lib/ui/contact_list/new_group_chat_sheet.dart(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
lib/ui/contact_list/new_group_chat_sheet.dart
🧠 Learnings (4)
📓 Common learnings
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
📚 Learning: 2025-09-16T07:24:07.453Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
📚 Learning: 2025-09-14T21:22:00.952Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#634
File: lib/config/providers/group_provider.dart:1130-1132
Timestamp: 2025-09-14T21:22:00.952Z
Learning: In the whitenoise_flutter codebase, the _updateGroupInfo method in GroupsNotifier performs optimistic updates that directly modify Group objects in the provider state (groups list and groupsMap). For non-DM groups, the display name comes from group.name, so updating the Group object directly is sufficient to reflect name changes in the UI without needing to refresh the separate display name cache.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
📚 Learning: 2025-09-07T13:10:16.542Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#597
File: lib/config/providers/group_provider.dart:311-314
Timestamp: 2025-09-07T13:10:16.542Z
Learning: In the whitenoise_flutter codebase, the User class used in group_provider.dart (and similar contexts) is presentational only, not the actual user class from the Rust API. There are plans to remove this User class and replace it with UserProfileData, similar to the planned consolidation with ContactModel.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (2)
lib/ui/contact_list/new_group_chat_sheet.dart (2)
11-11: LGTM: assets import is appropriate.Aligns with new search/paste UI.
15-18: LGTM: centralized paste helper and UI widgets.Good reuse of ClipboardUtils and WN UI components.
josefinalliende
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A tiny suggestion, but worked perfect for npubs splitted in groups of 5. 👍🏻 Approved! ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
lib/ui/contact_list/new_chat_bottom_sheet.dart (1)
581-606: Fix compile error: invalid EdgeInsets scaling extension usage.
const EdgeInsets.all(13).wwon’t compile. Apply scaling to the numeric and dropconst.- padding: const EdgeInsets.all(13).w, + padding: EdgeInsets.all(13.w),
🧹 Nitpick comments (5)
test/utils/clipboard_utils_test.dart (2)
298-353: Add a whitespace-only clipboard case.Edge case: clipboard text containing only whitespace (e.g., " \n\t ") should likely be treated as empty/info toast. Add a test to lock this in (or clarify expected behavior).
355-387: Parity nit: also assert autoDismiss for null clipboard.For consistency with the “empty clipboard” group, assert
autoDismiss == truehere as well.lib/ui/contact_list/new_chat_bottom_sheet.dart (3)
36-36: Localize the new sheet title.Replace the hardcoded 'Start New Chat' with AppLocalizations (or the
context.l10nextension) to comply with the project’s i18n guideline.
76-91: Make npub detection case‑insensitive and fix the misleading comment.Current logic misses uppercase inputs like 'NPUB…'. Also, the comment mentions “hex‑like” but code doesn’t handle it. Either handle hex here or update the comment. Suggested minimal fix (case‑insensitive) + add explicit types per guidelines:
- final originalText = _searchController.text; - String processedText = originalText; - - // Only remove whitespace if it looks like a public key (starts with npub or is hex-like) - if (originalText.startsWith('npub')) { + final String originalText = _searchController.text; + String processedText = originalText; + // Remove whitespace for npub-like inputs (case-insensitive). + final String lower = originalText.toLowerCase(); + if (lower.startsWith('npub')) { processedText = originalText.replaceAll(RegExp(r'\s+'), '');
354-399: Remove redundant async/await in paste onTap.No need to mark
onTapasync just to immediately await. This also shortens the callback.- WnIconButton( + WnIconButton( iconPath: AssetsPaths.icPaste, - onTap: - () async => await ClipboardUtils.pasteWithToast( - ref: ref, - onPaste: (text) { - _searchController.text = text; - }, - ), + onTap: () => ClipboardUtils.pasteWithToast( + ref: ref, + onPaste: (text) => _searchController.text = text, + ), padding: 14.w, size: 44.h, ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
lib/ui/contact_list/new_chat_bottom_sheet.dart(6 hunks)lib/ui/contact_list/new_group_chat_sheet.dart(3 hunks)test/utils/clipboard_utils_test.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/ui/contact_list/new_group_chat_sheet.dart
🧰 Additional context used
📓 Path-based instructions (2)
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
test/utils/clipboard_utils_test.dartlib/ui/contact_list/new_chat_bottom_sheet.dart
**/*_test.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*_test.dart: Follow the Arrange-Act-Assert convention for tests.
Name test variables clearly. Follow the convention: inputX, mockX, actualX, expectedX, etc.
Write unit tests for each public function. Use test doubles to simulate dependencies, except for third-party dependencies that are not expensive to execute.
Write acceptance tests for each module. Follow the Given-When-Then convention.
Use the standard widget testing for Flutter.
Files:
test/utils/clipboard_utils_test.dart
🧠 Learnings (7)
📓 Common learnings
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
📚 Learning: 2025-09-16T07:24:07.453Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.453Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-07T02:08:09.199Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/domain/models/contact_model.dart:36-41
Timestamp: 2025-09-07T02:08:09.199Z
Learning: The issue of ContactModel.publicKey potentially being set to an empty string when pubkey.toNpub() conversion fails (causing collision/lookup issues) is being addressed in PR #597 in the whitenoise_flutter codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-05T00:08:34.509Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/config/providers/active_account_provider.dart:140-146
Timestamp: 2025-09-05T00:08:34.509Z
Learning: josefinalliende prefers centralizing validation logic (like trimming whitespace) in providers rather than handling it defensively at every consumer site. This approach was applied to activePubkeyProvider in the whitenoise_flutter codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-07T02:15:31.931Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#594
File: lib/src/rust/api/utils.dart:12-16
Timestamp: 2025-09-07T02:15:31.931Z
Learning: The lingering PublicKey references in lib/config/providers/auth_provider.dart, lib/config/providers/group_provider.dart, and rust_builder/cargokit/build_tool/lib/src/options.dart identified during the utils.dart API cleanup were fixed in PR #597 in the whitenoise_flutter codebase.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-08-23T11:02:28.308Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#527
File: lib/ui/core/ui/wn_avatar.dart:1-6
Timestamp: 2025-08-23T11:02:28.308Z
Learning: In the whitenoise_flutter codebase, flutter_screenutil is re-exported through lib/ui/core/themes/src/app_theme.dart, so files that import app_theme.dart do not need to directly import flutter_screenutil to use .w, .h, .sp extensions.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
📚 Learning: 2025-09-16T06:28:24.611Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#640
File: lib/ui/chat/services/chat_dialog_service.dart:21-25
Timestamp: 2025-09-16T06:28:24.611Z
Learning: In lib/ui/core/ui/wn_bottom_sheet.dart, the WnBottomSheet.show method has barrierDismissible parameter that defaults to false, not true.
Applied to files:
lib/ui/contact_list/new_chat_bottom_sheet.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (5)
test/utils/clipboard_utils_test.dart (4)
216-233: Good test helper for mocking Clipboard.getData.Scoped handler is clear and contained to this group. Nice.
235-246: Solid setup/teardown hygiene.Resetting the platform handler in tearDown prevents cross-test leakage.
247-263: Happy path covered: callback invoked and success toast asserted.This validates both behavior and user feedback.
389-450: Error path coverage looks complete.Verifies no callback, error type, auto-dismiss, and default/custom messages.
lib/ui/contact_list/new_chat_bottom_sheet.dart (1)
21-25: Right abstraction: use ClipboardUtils and WnIconButton.Importing and reusing shared utilities/components keeps behavior consistent across screens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
lib/ui/contact_list/new_group_chat_sheet.dart (2)
70-90: Don’t mutate the controller on change; use raw trimmed text for query.Mutating
_searchController.valuemid-typing is jarring and was flagged previously. Sanitize only for key matching (and on paste), not while the user types. Also remove intra-function blank lines per guidelines.Apply this diff:
void _onSearchChanged() { - final originalText = _searchController.text; - String processedText = originalText; - - // Only remove whitespace if it looks like a public key (starts with npub or is hex-like) - if (originalText.startsWith('npub')) { - processedText = originalText.replaceAll(RegExp(r'\s+'), ''); - - // Update the controller if we removed whitespace - if (originalText != processedText) { - _searchController.value = _searchController.value.copyWith( - text: processedText, - selection: TextSelection.collapsed(offset: processedText.length), - ); - } - } - setState(() { - _searchQuery = processedText; + final String text = _searchController.text; + _searchQuery = text.trim(); }); }
146-159: Use sanitized variant only for key matching; keep name/NIP‑05 matching unchanged.This fixes npub-with-spaces search without rewriting the input and aligns with issue #613.
Apply this diff:
- return contactsWithoutCreator - .where( - (contact) => - contact.displayName.toLowerCase().contains( - _searchQuery.toLowerCase(), - ) || - (contact.nip05?.toLowerCase().contains( - _searchQuery.toLowerCase(), - ) ?? - false) || - contact.publicKey.toLowerCase().contains( - _searchQuery.toLowerCase(), - ), - ) - .toList(); + final String q = _searchQuery.toLowerCase(); + final String keyQ = _searchQuery.replaceAll(RegExp(r'\s+'), '').toLowerCase(); + return contactsWithoutCreator + .where((contact) => + contact.displayName.toLowerCase().contains(q) || + (contact.nip05?.toLowerCase().contains(q) ?? false) || + contact.publicKey.toLowerCase().contains(keyQ)) + .toList();
🧹 Nitpick comments (2)
lib/ui/contact_list/new_group_chat_sheet.dart (2)
177-209: Sanitize only on paste; avoid redundant async/await.Normalize pasted npubs by stripping whitespace, but don’t sanitize during typing. Also drop
async => await.Apply this diff:
- WnIconButton( + WnIconButton( iconPath: AssetsPaths.icPaste, - onTap: - () async => await ClipboardUtils.pasteWithToast( + onTap: () => ClipboardUtils.pasteWithToast( ref: ref, - onPaste: (text) { - _searchController.text = text; - }, + onPaste: (String text) { + final String v = text.trimLeft(); + final String normalized = + v.startsWith('npub') ? v.replaceAll(RegExp(r'\s+'), '') : v; + _searchController.text = normalized; + }, ), padding: 14.w, size: 44.h, ),
197-209: Add accessibility label to paste button.Ensure screen readers can discover the control.
If
WnIconButtonsupports a11y labels/tooltips, set one (e.g., “Paste”). Otherwise, wrap withSemantics(label: 'Paste', button: true, child: ...).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
lib/ui/contact_list/new_group_chat_sheet.dart(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart
📄 CodeRabbit inference engine (.cursor/rules/flutter.mdc)
**/*.dart: Always declare the type of each variable and function (parameters and return value). Avoid using 'any'. Create necessary types.
Don't leave blank lines within a function.
One export per file.
Use PascalCase for classes.
Use camelCase for variables, functions, and methods.
Use underscores_case for file and directory names.
Use UPPERCASE for environment variables. Avoid magic numbers and define constants.
Start each function with a verb.
Use verbs for boolean variables. Example: isLoading, hasError, canDelete, etc.
Use complete words instead of abbreviations and correct spelling, except for standard and well-known abbreviations (API, URL, i, j, err, ctx, req, res, next).
Write short functions with a single purpose. Less than 20 instructions.
Name functions with a verb and something else. If it returns a boolean, use isX or hasX, canX, etc. If it doesn't return anything, use executeX or saveX, etc.
Avoid nesting blocks by early checks and returns, or extraction to utility functions.
Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting. Use arrow functions for simple functions (less than 3 instructions). Use named functions for non-simple functions.
Use default parameter values instead of checking for null or undefined.
Reduce function parameters using RO-RO: use an object to pass multiple parameters and to return results. Declare necessary types for input arguments and output.
Use a single level of abstraction in functions.
Don't abuse primitive types and encapsulate data in composite types.
Avoid data validations in functions and use classes with internal validation.
Prefer immutability for data. Use readonly for data that doesn't change. Use 'as const' for literals that don't change.
Declare interfaces to define contracts.
Write small classes with a single purpose. Less than 200 instructions, less than 10 public methods, less than 10 properties.
Use exceptions to handle errors you don't expect. If you catch an exception, it sh...
Files:
lib/ui/contact_list/new_group_chat_sheet.dart
🧠 Learnings (4)
📓 Common learnings
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.489Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
📚 Learning: 2025-09-16T07:24:07.489Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#642
File: lib/ui/contact_list/new_chat_bottom_sheet.dart:324-336
Timestamp: 2025-09-16T07:24:07.489Z
Learning: In the whitenoise_flutter project, the user Quwaysim prefers to handle security improvements incrementally across different PRs rather than bundling them all together. Input trimming for search functionality was handled in PR #613, and private key security measures are planned for PR #505.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
📚 Learning: 2025-09-14T21:22:00.962Z
Learnt from: Quwaysim
PR: parres-hq/whitenoise_flutter#634
File: lib/config/providers/group_provider.dart:1130-1132
Timestamp: 2025-09-14T21:22:00.962Z
Learning: In the whitenoise_flutter codebase, the _updateGroupInfo method in GroupsNotifier performs optimistic updates that directly modify Group objects in the provider state (groups list and groupsMap). For non-DM groups, the display name comes from group.name, so updating the Group object directly is sufficient to reflect name changes in the UI without needing to refresh the separate display name cache.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
📚 Learning: 2025-09-07T13:10:16.542Z
Learnt from: josefinalliende
PR: parres-hq/whitenoise_flutter#597
File: lib/config/providers/group_provider.dart:311-314
Timestamp: 2025-09-07T13:10:16.542Z
Learning: In the whitenoise_flutter codebase, the User class used in group_provider.dart (and similar contexts) is presentational only, not the actual user class from the Rust API. There are plans to remove this User class and replace it with UserProfileData, similar to the planned consolidation with ContactModel.
Applied to files:
lib/ui/contact_list/new_group_chat_sheet.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Flutter CI
🔇 Additional comments (2)
lib/ui/contact_list/new_group_chat_sheet.dart (2)
11-18: LGTM on imports.New UI and clipboard utilities are used below and keep concerns well-scoped.
182-183: Localize hardcoded hint textSearch returned no matches for the literal 'Search contact or public key...'; confirm lib/ui/contact_list/new_group_chat_sheet.dart (lines 182–183) contains this hardcoded hint and replace it with AppLocalizations.of(context)!.searchContactOrKeyHint.
- Also localize the sheet title, empty/error strings, and buttons.
…/github.com/parres-hq/whitenoise_flutter into 477-past-npub-icon-button-in-profile-search
josefinalliende
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Tried it locally with both npub formats (grouped in 4 chars and in 5) and works perfect for me
Description
Added #477. This adds the paste button beside the npub/user search in the profile search/start new chat bottom sheet. Also made some minor UI changes to match the design.
Edit: fixes #613 too to format pasted npubs with whitespaces.
Type of Change
Checklist
just precommitto ensure that formatting and linting are correctjust check-flutter-coverageto ensure that flutter coverage rules are passingCHANGELOG.mdfile with your changes (if they affect the user experience)Summary by CodeRabbit
New Features
Style
Bug Fixes
Tests