Commit Graph
178 Commits
Author SHA1 Message Date
Javier G. Montoya S.andGitHub 8d6480c51f chore(rust): bump whitenoise-rs (#365) 2026-02-22 02:54:43 -03:00
PepiandGitHub cc8ab754d6 Fix notifications arriving on foreground after accepting invite (#361)
* fix: notifications arriving on foreground

* docs: update changelog
2026-02-21 08:34:51 +01:00
PepiandGitHub aa31039d60 Message bubbles style (#329)
* feat: add wn message bubble to match design

* feat: add chat message bubble that uses wn message bubble

* feat: adjust message reactions

* feat: use new message bubble in chat invite, chat screen and message actions screen

* docs: update changelog
2026-02-20 22:46:46 -03:00
emir yorulmazandGitHub 50435daca1 Remove unimplemented chat list menu actions (#358) 2026-02-21 00:36:13 +03:00
Javier G. Montoya S.andGitHub 2f0e5f4d50 feat(user_search): expand the search unto up to radius 4 (#357)
also bump whitenoise crate
2026-02-20 18:35:51 -03:00
PepiandGitHub c6a4fe423a Fix/linting issues (#359)
* fix: spanish translation

* fix: autofixable linting issues

* chore: update widgetbook pubspec.lock
2026-02-20 18:17:53 -03:00
AndrewandGitHub 6113687a5b feat: add share button under "Invite to White Noise" callout (#354)
* feat: add share button under "Invite to White Noise" callout

* fix: CHANGELOG link style

* feat: add mocked share_plus test for invite button

* fix: code review & linting
2026-02-20 17:50:17 -03:00
emir yorulmazandGitHub f22410f60e Chat info: search and add to group (#355) 2026-02-20 22:37:43 +03:00
JeffGandGitHub ae203e9d65 Update iOS icons and app name for staging (#330)
* Update iOS icons and app name for staging

* fix(ios): harden build script and correct Release display name

- Add cargo check to environment validation in build_ios.sh
- Add existence check before cd rust to give informative errors
- Replace fragile cd/pod install/cd with pushd/popd and error handling
- Add POSIX-compliant trailing newline to build_ios.sh
- Fix project-level Release APP_DISPLAY_NAME ("White Noise staging" → "White Noise") to match target-level value

* feat(android): add staging flavor launcher icons

Add ic_launcher_foreground, ic_launcher_background, ic_launcher_monochrome,
and legacy ic_launcher PNGs for all densities (mdpi through xxxhdpi) plus
the mipmap-anydpi-v26 adaptive icon XML in the staging source set.

* fix(ios): add CocoaPods availability check to build script

* chore: replace LICENSE copies with symlinks to root

Fixes missing license warnings during iOS builds by ensuring
rust/ and rust_builder/ both symlink to the root LICENSE file.
2026-02-20 19:50:04 +01:00
JeffGandGitHub 373bb829c6 Fix OS back button closing app from chat screen (#353)
The chat screen is navigated to via GoRouter.go() (stack replacement),
leaving it as the root of the navigation stack with nothing to pop back
to. The in-app back button correctly called Routes.goToChatList(), but
the Android OS back button had no handler and defaulted to Navigator.pop()
on a root route, closing the app.

Wrap ChatScreen in PopScope(canPop: false) so the OS back gesture is
intercepted and redirected to goToChatList() instead.

Fixes #334
2026-02-20 19:49:24 +01:00
JeffGandGitHub e919e7bbeb fix: make dropdowns mutually exclusive and reduce transition duration (#337)
* fix: make dropdowns mutually exclusive using WnDropdownScope

Adds WnDropdownController and WnDropdownScope to WnDropdownSelector,
following the same pattern as WnListItemController/WnListItemScope.
When multiple WnDropdownSelector widgets are wrapped in a WnDropdownScope,
opening one automatically closes any other that is open.

Updates AppearanceScreen to use WnDropdownScope so the theme and language
dropdowns cannot both be open at the same time (fixes #332).

* fix: reduce slate content transition duration from 250ms to 150ms

* fix: set slate content transition duration to 200ms

* test: achieve 100% coverage on all files touched by this branch

- Add WnDropdownController unit tests (openItemKey getter, close no-op,
  open same key no-notify, controller lifecycle)
- Add WnDropdownSelector tests covering controller integration paths:
  toggle-closes via controller, selectOption via controller, disable-
  while-open with controller, non-ValueKey effectiveKey fallback
- Add use_dropdown_controller_test.dart for the new hook
- Add AppearanceScreen tests verifying exclusive dropdown behaviour
- Add WnSlateContentTransition duration assertion (200ms)
- Fix controller.close() called during build by deferring via
  addPostFrameCallback

* fix: revert incorrect Spanish translation change

The precommit l10n auto-fix incorrectly dropped the 'a' before
{userName} in addToGroupConfirmation. Restored to the correct
'¿Añadir a {userName} a {groupName}?' in both the ARB source and
generated file.
2026-02-20 17:56:59 +01:00
PepiandGitHub 36ca84870d Text drafts (#328)
* feat: expose get message by id in use chat messages to use it in drafts

* feat: add text draft logic in use chat input hook

* feat: use drafts in chat screen

* docs: update changelog
2026-02-20 13:53:02 -03:00
emir yorulmazandGitHub c8c3477743 Add to group from group info and start chat (#323)
* Translations

* Create use_groups.dart

* Routes

* Screens

* Tests

* Update CHANGELOG.md

* Cancel stale group fetches

* Invalidate requests on unmount

* fetchCounter.value++
2026-02-20 13:24:07 +03:00
PepiandGitHub 3e2e5890fa feat: add invalid key package message for callout in start chat (#325) 2026-02-20 05:05:37 -03:00
PepiandGitHub f55678cee6 Fix media tags to use MIP-04 v2 (#326)
* fix: add media file nonce to bridge

* fix: use mip04-v2 media tags with nonce
2026-02-20 05:05:13 -03:00
PepiandGitHub c5c7806b5b Show last message sender name in chat list groups (#322)
* feat: add sender name prefix for group chat list tiles

* docs: update changelog
2026-02-20 03:39:15 -03:00
Javier G. Montoya S.andGitHub 540b753846 feat(rust/src/api/drafts): add drafts api (#324) 2026-02-20 02:53:52 -03:00
PepiandGitHub 8b7b9e48e4 Images in chat (#249)
* refactor: remove unused animated pixel overlay widget

* feat: add base media placeholder widgets

* feat: add media thumbnail widget

* feat: add media download hook

* feat: add media display widgets

* feat: add media preview and modal widgets

* feat: add media upload support

* refactor: replace reply preview with chat message quote

* feat: integrate media into chat screen

* docs: update changelog

* test: replace magic number 844 with testDesignSize.height in WnTooltip test

* fix: remove thumbnail gradient overlay, center image in remaining space

* fix: constrain modal height so image fills remaining space below header

* test: improve coverage
2026-02-20 00:59:21 -03:00
Javier G. Montoya S.andGitHub d3898b2303 fix(user_search): use already in-memory contacts and bump rust crate for properly working search (#318) 2026-02-19 22:26:50 -03:00
Mubarak AuwalandGitHub bab7a76c9e feat: expose KeyPackageStatus enum in bridge (#308)
* feat: update bridge to expose KeyPackageStatus enum (#308)

Update whitenoise-rs to bd18293 and mdk-core to v0.6.0. Change
user_has_key_package return type from bool to KeyPackageStatus
(Valid/NotFound/Incompatible) and regenerate FRB bindings.

* fix: migrate Flutter code from bool to KeyPackageStatus

Update hook, screens, mocks, and tests to use the new
KeyPackageStatus enum instead of bool for key package checks.
2026-02-19 19:18:46 +01:00
PepiandGitHub e4b77a4e1c fix: avoid shrinkning issue on slate with system notice feedback (#320) 2026-02-19 14:25:35 -03:00
PepiandGitHub 616dbc60c2 Mark messages as read (#316)
* feat: add chat scroll down button to give the user a hint that has unread messages below

* feat: add get account group to flutter rust bridge to vet last read message id

* feat: add mark as read hook and use it in chat scroll hook

* feat: scroll in chat screen considering unread messages

* feat: mark as read when accepting chat invites adn show scroll down button

* docs: update changelog
2026-02-19 11:02:39 -03:00
JeffGandGitHub c3b4a19098 fix: handle app upgrade crashes from incompatible data and foreground service receivers (#312)
* fix: handle app upgrade crashes from incompatible data and foreground service

When upgrading from an older version, multiple issues caused crashes:

1. The Rust whitenoise crate's secrets store format changed, causing
   "Secrets store error: Key not found" during initialization. Since
   the Rust singleton (tokio::sync::OnceCell) can't be reinitialized
   after partial failure, a version marker file now detects stale data
   and wipes the data directory before Rust init runs.

2. The flutter_foreground_task plugin stored foregroundServiceType
   0x201 (dataSync|shortService) in native SharedPreferences, but the
   manifest only declares dataSync (0x01). Android rejected
   startForeground() with IllegalArgumentException. A one-time cleanup
   in MainActivity.onCreate() clears these native prefs.

3. FlutterSecureStorage's internal migration from EncryptedSharedPreferences
   re-introduced the old active_account_pubkey after deleteAll(). Fixed by
   calling readAll() first to trigger the migration, then deleteAll().

4. The plugin's RebootReceiver and RestartReceiver caused cascade crashes
   on package update. Both are now disabled via manifest merge overrides.

* chore: remove stale url_launcher from generated plugin files and add build improvements

Remove url_launcher references from Linux/Windows plugin registrants
(dependency was already removed from pubspec.yaml). Add split APK,
AAB build targets and quiet spinner to OpenSSL build script.
2026-02-19 14:47:51 +01:00
JeffGandGitHub 0e4641888f Remove chat filter pills from search header (#319)
The Chats/Archive filter chips in the pull-down search header are not
hooked up to anything and won't be before release. Remove them from
the widget tree and reduce the header height accordingly. The
WnFilterChip widget itself is kept for future use.
2026-02-19 14:18:01 +01:00
emir yorulmazandGitHub c0c451887c Group info & management (#315)
* Hooks

* Translations

* Routes

* Screens

* Widgets

* Tests

* Update CHANGELOG.md

* Group-specific success msg

* Group specific error msg

* Add missing error msgs and tests

* Remove unused system notice from group info
2026-02-19 13:40:17 +03:00
emir yorulmazandGitHub 97955e79d8 Copy message (#317)
* Copy message

* Update CHANGELOG.md

* Add addTearDown handlers
2026-02-19 12:20:40 +03:00
Danny MandGitHub 2bd78ada0c when apk deployed as "preview" before, making it visible only to me, this fixes it (#311) 2026-02-18 15:16:53 +01:00
emir yorulmazandGitHub c35f592284 Create group (#288)
* Translations

* Hooks

* Routes

* Screens

* Tests

* Update CHANGELOG.md

* tapping close button navigates back

* find.byKey

* New design

* 'Create group'

* Pass selectedUsers as param to hook

* Add missing spacing for user list in set up group

* use back button for headers in create group flow
2026-02-18 16:00:47 +03:00
PepiandGitHub c6c907ec9a Feat/invites in chatlist improvements (#310)
* fix: prevent invites reordering on new messages in chat list

* feat: show last message for invites in chat list

* docs: update changelog
2026-02-18 09:17:06 -03:00
JeffGandGitHub 7b795ab2c1 Improve signup name UX and compact add-profile slate (#313)
* Improve signup name UX and compact add-profile slate

* Add PR reference to changelog entry

* Upgrade unique_names_generator to v3
2026-02-18 12:52:12 +01:00
a31e528776 Refactor camera permission flow (#194)
* Refactor camera permission flow

* Update CHANGELOG.md

* chore: add permission handler

* feat: add scanner translations

* fix: request camera permission and use permission handler to go to settings in case of denied

* fix: show camera option in ios settings

---------

Co-authored-by: josefinalliende <mariajosefinaalliende@gmail.com>
2026-02-18 14:43:15 +03:00
JeffGandGitHub 6c830c8eb1 chore(ci): add PR labeler and improve coverage reporting (#304)
* chore(ci): add PR labeler and improve coverage reporting

* chore(ci): split lint test and coverage jobs

* fix(ci): dedupe coverage history entries by sha

* fix(ci): use github.workspace in cache paths

* fix(ci): run flutter tests once for coverage

* fix(ci): consume coverage from shared test artifact

* fix(ci): align coverage guidance and add checkout

* fix(ci): checkout before downloading coverage artifact

* chore(coderabbit): dedupe title ignore keywords

* docs: refine widget naming conventions into three categories

Encode reviewer feedback distinguishing design system widgets (Wn prefix),
complex reusable widgets (no prefix), and screen-scoped widgets (screen
name prefix) in both .coderabbit.yaml and AGENTS.md.

* fix(ci): cache lcov apt package to avoid repeated installs
2026-02-18 10:04:20 +01:00
JeffGandGitHub 3666e69ca3 fix: add timeout and loading state to delete all data flow (#306)
* fix: add timeout and loading state to delete all data flow (#257)

The delete all data operation could hang forever with no feedback if the
Rust call never completed. Additionally, the confirmation overlay would
dismiss before the operation started, causing a visual jump back to the
privacy screen during loading.

- Add 30-second timeout to deleteAllData hook to prevent infinite loading
- Show loading state on the confirmation button instead of popping back
- Disable cancel/back/dismiss while operation is in progress
- Add onConfirmAsync support to WnConfirmationSlate for async operations

* fix: reduce delete all data timeout to 10 seconds

* refactor: remove dead sync branch from WnConfirmationSlate.show()

Make onConfirmAsync required since all callers pass it, removing the
unreachable sync SafeArea path and duplicate tests that exercised it.
2026-02-18 09:20:23 +01:00
JeffGandGitHub 44d7795734 Implement chat info screen redesign from Figma (#303)
* Implement chat info sheet redesign and interactions

* Add PR link to chat info changelog entry

* Localize chat info labels for non-English locales

* Address chat info widget review cleanup

* Use follow/unfollow copy in chat info actions
2026-02-18 08:25:19 +01:00
Danny MandGitHub bfa403e21a answer the age old question, when apk (#294) 2026-02-17 22:41:40 +01:00
JeffGandGitHub f2d202b4f3 fix: resolve sender metadata for push notifications when displayName is missing (#305)
* fix: resolve sender metadata for push notifications when displayName is missing (#282)

When the Rust crate's NotificationUpdate lacks a sender displayName
(common for new invites), fetch metadata via UserService before
formatting the notification. Falls back to 'Unknown user' if the
fetch fails or returns no name fields.

* fix: use distinct values in senderName precedence test to verify actual precedence
2026-02-17 20:51:27 +01:00
JeffGandGitHub a4147776d5 feat: add 40px variant to WnInputFieldButton (#285)
* feat: add 40px variant to WnInputFieldButton (#276)

Introduce WnInputFieldButtonSize enum with size36, size40, and size48
variants, each encoding both dimension and icon size. This replaces the
previous WnInputSize-based sizing on WnInputFieldButton with a dedicated
buttonSize parameter, enabling the new 40px button for 56px input fields.

* refactor: extract WnInputFieldButton, internalize inline action sizing

Address PR #285 review feedback:

- Extract WnInputFieldButton and WnInputFieldButtonSize into
  dedicated wn_input_field_button.dart file
- Add `filled` parameter (default true) supporting transparent variant
  used by WnInputPassword and WnCopyableField
- Replace WnInput's `inlineAction: Widget?` with `inlineActionIcon`,
  `inlineActionOnPressed`, and `inlineActionFilled` so the input
  manages button sizing internally based on WnInputSize
- Refactor WnInputPassword inline actions to use WnInputFieldButton
  instead of manual GestureDetector/Container
- Add WnInputSize.inlineActionButtonSize getter to centralize
  size44→size36, size56→size48 mapping
- Update widgetbook with filled/unfilled showcase and knobs
2026-02-17 11:56:41 +01:00
JeffGandGitHub ca8d6a87bf feat: add WnUserItem component (#284)
* feat: add WnUserItem component (#279)

Simple row widget displaying a user avatar, name, and optional label.
Includes 100% test coverage and widgetbook showcase entry.

* feat: add image variant to WnUserItem widgetbook showcase

* feat: add size variants (small/medium/big) with checkbox and npub support

Redesigns WnUserItem with three Figma-matched sizes:
- Small: avatar(xSmall) + name + optional label
- Medium: avatar(small) + name + npub(WnMiddleEllipsisText, 2 lines) + checkbox
- Big: avatar(medium) + name + npub(WnMiddleEllipsisText, 2 lines) + checkbox, fixed height

Adds onTap, isSelected, showCheckbox props. 28 tests, 100% coverage.

* fix: use minHeight instead of fixed height on big variant

The fixed height of 76px was clipping the second line of npub text.
Using minHeight allows the container to grow to fit content.
2026-02-17 11:56:27 +01:00
JeffGandGitHub 147b6bccde feat(auth): multi-step login with relay resolution UI (#281)
* feat(auth): multi-step login with relay resolution UI

Replace the single-shot login API with a multi-step flow that gracefully
handles missing relay lists instead of crashing. When relay lists aren't
found on the network, users are now presented with a relay resolution
screen offering two paths: provide a custom relay URL to search, or
publish default relay lists.

- Update whitenoise-rs to multi-step login PR (3435fd9)
- Add LoginResult/LoginStatus/LoginError types to Rust API bridge
- Add login_start, login_publish_default_relays, login_with_custom_relay,
  login_cancel bridge functions (nsec + external signer variants)
- Refactor AuthNotifier, hooks, and AndroidSignerService for multi-step flow
- Add RelayResolutionScreen with relay URL input and default relays option
- Add structured login error messages (invalid key, timeout, no connections)
- Remove obsolete AccountSettings bridge (removed upstream)

Closes marmot-protocol/whitenoise#46, marmot-protocol/whitenoise#143

* fix(auth): standardize error keys, add translations, maximize test coverage

- Standardize all login hook errors to l10n keys instead of raw English
  strings (paste errors, all 5 LoginError variants)
- Remove redundant useEffect cleanup from hooks (useTextEditingController
  handles its own disposal)
- Wrap fire-and-forget userMetadata call with unawaited() for clarity
- Simplify relay resolution error resolver to two-branch switch
- Translate all 15 new l10n keys into DE, ES, FR, IT, PT, RU, TR
- Add 4 new l10n keys: loginErrorNoLoginInProgress, loginErrorInternal,
  loginPasteNothingToPaste, loginPasteFailed
- Add tests for all uncovered provider, screen, hook, and service paths

Coverage: 99.43% overall, 100% on all changed files

* fix(auth): remove unused hook param, disable buttons during loading, assert loginCancel

- Remove unused isExternalSigner parameter from useRelayResolution hook
  (the screen uses it to select callbacks, not the hook itself)
- Disable both relay resolution buttons while loading to prevent
  concurrent requests
- Add assertion to loginCancel test verifying the Rust API receives
  the correct pubkey

* fix(auth): restore nsec cleanup on dispose, use consistent error key

- Restore useEffect cleanup that clears nsec from TextEditingController
  on widget dispose (security fix from defb482 accidentally removed)
- Replace orphaned 'relayResolutionPublishFailed' error key with
  'loginErrorGeneric' for consistency with tryCustomRelay error handling
- Regenerate flutter_rust_bridge code after rebase onto master

* fix(auth): independent button loading, relay URL prefill and validation

- Split isLoading into isPublishingDefaults and isSearchingRelay so each
  button shows its own loading indicator while the other is just disabled
- Prefill relay URL input with wss:// matching the network settings pattern
- Add debounced relay URL validation (shared utility extracted from
  use_add_relay) with inline error display via WnInput.errorText
- Wrap fire-and-forget userMetadata call with error handling in
  _completeLogin to prevent unhandled async exceptions
- Replace map-iteration-order-dependent testNpubToHex.values.first with
  explicit testPubkeyA constant in mock
- Add mounted guard (useRef<bool>) to skip state updates after unmount
- Map caught ApiError variants to structured l10n keys instead of
  hardcoding loginErrorGeneric; expand _resolveError to match

* test: add coverage for metadata fetch failure, validation reset, and external signer method routing

- Test that login completes even when fire-and-forget userMetadata fails
- Test that clearing relay URL back to wss:// prefix resets validation state
- Add invocation flags to mock auth notifier and assert external signer
  tests call the correct methods (not the regular login methods)
2026-02-17 11:41:56 +01:00
JeffGandGitHub 5aea549f6e fix: remove manual scroll-to-bottom on signup screen keyboard open (#287)
Remove the useEffect that scrolled to maxScrollExtent when the keyboard
appeared, which was hiding the name input field. Flutter's Scaffold with
resizeToAvoidBottomInset (default true) and built-in focus management
already handle scrolling the focused field into view natively.

Closes #144
2026-02-17 08:17:46 +01:00
JeffGandGitHub 815be13c43 refactor(theme): rename Fill Content/Destructive to Fill Content/Quaternary (#283)
* refactor(theme): rename fillContentDestructive to fillContentQuaternary

This token is now used beyond destructive contexts, so the old name
was misleading. Rename to fillContentQuaternary to match the existing
primary/secondary/tertiary naming convention.

Closes #274

* style: break long fillContentQuaternary lerp line into multiline
2026-02-16 19:13:38 +01:00
027089af56 Feat/local notifications (#262)
* chore: add flutter local notifications and flutter foreground task deps

* feat: add bridge notifications methods

* feat: add foreground service to keep notifications stream alive

* feat: add notification service and provider

* feat: add provider to store active chat for notification purposes

* feat: add active chat provider to store if we are in a chat screen

* feat: add active chat route observer to clear active chat on navigation

* feat: add use active chat hook to cancel notifications on active chat

* feat: use active chat hook on invite and chat screen

* feat: translate notifications messages in notification provider

* fix: improve notification system reliability and reduce duplicate state tracking (#271)

* fix: improve notification system reliability and reduce duplicate state tracking

- Simplify useActiveChat hook: remove duplicate set/clear that overlaps
  with ActiveChatRouteObserver, keep only lifecycle handling and
  notification cancellation
- Fix provider modification during widget build: defer
  ActiveChatRouteObserver state updates via Future.microtask
- Add error handling in _initializeAndListen with try/catch
- Wire up battery optimization exemption request after foreground
  service start
- Replace non-deterministic String.hashCode with SHA-256-based
  notification ID generation
- Remove unused RECEIVE_BOOT_COMPLETED permission from manifest
- Expand test coverage for disabled-mode foreground service,
  notification service, and deterministic ID generation

* fix: restore active chat tracking in useActiveChat hook with deferred provider updates

The hook's setActiveChat/clearActiveChat calls were removed in the previous
commit, breaking notification clearing — users received notifications for
the chat they were actively viewing.

Restore the calls but defer them via Future.microtask() to avoid Riverpod's
'provider modification during build' error. Add ref.mounted guards to the
ActiveChatNotifier to handle disposal edge cases.

* feat: improve notifications for multiple accounts (#272)

* fix: improve notification system reliability and reduce duplicate state tracking

- Simplify useActiveChat hook: remove duplicate set/clear that overlaps
  with ActiveChatRouteObserver, keep only lifecycle handling and
  notification cancellation
- Fix provider modification during widget build: defer
  ActiveChatRouteObserver state updates via Future.microtask
- Add error handling in _initializeAndListen with try/catch
- Wire up battery optimization exemption request after foreground
  service start
- Replace non-deterministic String.hashCode with SHA-256-based
  notification ID generation
- Remove unused RECEIVE_BOOT_COMPLETED permission from manifest
- Expand test coverage for disabled-mode foreground service,
  notification service, and deterministic ID generation

* feat: show receiver name in notifications when multiple accounts are logged in

When more than one account exists, notification titles include the
receiver's display name in parentheses (e.g. 'Alice (MyAccount)') so
users know which account the notification is for. Single-account users
see no change.

Closes #265

* feat: switch to correct account when notification is tapped

Include receiver pubkey in the notification payload so the tap handler
can switch to the correct account before navigating to the chat or
invite screen. Exposes a navigator key from Routes so navigation can
happen outside the widget tree.

* fix: use fresh account count per notification and JSON-encode payloads

- Fetch accounts on each notification instead of capturing count once at
  init, so multi-account display stays current when accounts change
- Replace pipe-delimited notification payload with JSON encoding to
  avoid misparse when groupId contains '|' characters
- Add validation and error handling for malformed payloads
- Expand tests for JSON payload format and edge cases

* fix: address review feedback and upgrade flutter_local_notifications to v20

- Upgrade flutter_local_notifications ^19.0.0 → ^20.1.0 (named params)
- Upgrade crypto ^3.0.6 → ^3.0.7
- Bump Java compatibility to 17 for v20 compatibility
- Guard _initializeAndListen against provider disposal with ref.mounted
- Change _initializeAndListen to void return (fire-and-forget)
- Make Future.microtask timing consistent in useActiveChat hook
- Add _initialized warning in cancelForGroup for consistency
- Remove non-essential comments in onRepeatEvent
- Use valid 64-char hex pubkeys in tests
- Fix uninitService test to assert on its own mock

* fix: await show, validate payloads strictly, use realistic test pubkeys

- Await notificationService.show in _handleNotificationUpdate so errors
  propagate to the stream's try/catch
- Wrap stream callback in try/catch to prevent unhandled async exceptions
- Reject unknown triggers and empty receiverPubkey in _handleNotificationTap
- Replace placeholder pubkeys (pk1/pk2) with valid 64-char hex strings
- Add tests for empty receiverPubkey and unknown trigger rejection

* test: improve notification coverage from 98.05% to 99.40%

- Add tests for handleNotificationUpdate (active chat skip, multi-account
  receiver name, DM/group formatting, correct pubkey forwarding)
- Add tests for requestPermission (null plugin, granted, denied, null result)
- Add tests for foregroundServiceProvider and notificationServiceProvider
- Fix uninitService test to use its own mock
- Add coverage exclusions for platform-gated code that requires Android
  runtime (providers, _initializeAndListen, _onNotificationTap,
  _navigateToNotificationTarget, _KeepAliveTaskHandler, static
  FlutterForegroundTask calls)
- Make handleNotificationUpdate @visibleForTesting for direct testing

---------

Co-authored-by: JeffG <202880+erskingardner@users.noreply.github.com>
2026-02-16 14:36:05 +01:00
PepiandGitHub 6a9883bc5d feat: add wn reaction with slate design (#261) 2026-02-14 23:31:27 -03:00
PepiandGitHub 781370cd67 feat: add wn message quote (#260) 2026-02-14 21:38:44 -03:00
PepiandGitHub 4124010f48 Add slate chat header (#258)
* feat: add wn slate chat header

* feat: use new header in inivite screen and add navigation to big avatar too

* feat: use new slate chat header in chat screen

* chore: delete old chat header widget

* docs: add widgetbook stories for slate headers

* docs: update changelog

* fix: adjust paddingg of wn slate avatar header and receive avatar color

* refactor: user wn slate avatar header in chat list screen
2026-02-14 21:38:17 -03:00
JeffGandGitHub cc4f1f8fe7 feat(settings): Privacy & security screen, rename to Appearance, update scroll effects (#254)
* feat(settings): add Privacy & security screen, rename App Settings to Appearance, update scroll edge effects

- Create Privacy & security screen with delete-all-data functionality (closes #247)
- Rename App Settings to Appearance, remove delete-all-data from it (closes #248)
- Add separator and secondary menu items for Donate/Developer settings
- Update scroll edge effect heights (slate: 40px, canvas: 196px) with smoother 3-stop gradient
- Add localization for all new strings across 8 languages
- Full test coverage for new and updated screens

* fix: title-case deleteAllAppData l10n keys, extract MockAuthNotifier to shared helper

* fix(l10n): use lowercase verb in German deleteAllAppData key

* fix(privacy): match Figma design for confirmation dialog and section labels

- WnConfirmationSlate: position at top of screen (not bottom), stack buttons vertically with 8px gap
- Privacy screen: section label uses semiBold16 with secondary color (grey) per design
- Confirmation dialog: use action-specific title/message/button text instead of generic
- Add deleteAllAppDataConfirmation and deleteAllAppDataWarning l10n keys across all 8 languages

* fix(confirmation): use back button instead of close X in confirmation slate
2026-02-14 17:34:29 +01:00
Javier G. Montoya S.andGitHub a3b69a88b8 feat(rust/src/api/account_settings): add account settings (notifications_enabled) rust api to the bridge (#259) 2026-02-13 22:20:28 -03:00
Danny MandGitHub d090cea9b7 make amber work without checking "I fully trust this application" (#255) 2026-02-13 15:33:02 +01:00
JeffGandGitHub feaf2177e8 feat(login): improve Amber login UX and fix disabled button opacity (#250)
* feat(login): improve Amber login UX and fix disabled button opacity

Rename "Login with Signer" to "Login with Amber" for clarity across
all locales. Disable the nsec login button when the field is empty
instead of keeping it always enabled. The Amber button is now always
outline style rather than swapping primary/outline based on input state.

Fix disabled button rendering to match Figma: apply 0.25 opacity to
the entire button container instead of individual color channels. The
previous per-color alpha approach made text nearly invisible in light
mode. This affects all button types (primary, outline, ghost, overlay,
destructive).

Add `just run` convenience command for running with flavor.

Closes #191

* chore: add Eclipse/Android Studio project files to gitignore

* chore: fix gitignore comment and add .classpath to Eclipse entries

* fix(button): remove disabled opacity — render disabled buttons at full opacity

* style(button): apply prefer_final_locals lint fix
2026-02-13 15:17:49 +01:00
JeffGandGitHub defb48234e fix(security): clear clipboard after copying private key and clean up nsec references (#251)
* fix(security): clear clipboard after copying private key and clean up nsec references (#29)

Add useClipboardGuard hook that clears the system clipboard 60 seconds
after copying the private key, reducing the window where the nsec is
accessible to other apps. Also clear the TextEditingController in
useLoginWithNsec on dispose to remove the nsec from the controller
promptly.

* fix: await Clipboard.setData in timer callback and add screen-level clipboard guard tests

Make the Timer callback async so exceptions from the Clipboard.setData
Future are properly caught by the existing try/catch. Add integration
tests to both ProfileKeysScreen and SignOutScreen verifying the clipboard
is cleared 60 seconds after copying the private key.

* fix: persist clipboard guard timer across screen navigation

Use a module-level timer instead of a hook-scoped ref so the clipboard
is cleared even after navigating away from the keys/sign-out screen.
Previously the timer was cancelled on widget dispose, meaning the
clipboard would only be cleared if the user stayed on the screen for
the full 60 seconds.

Addresses review feedback from untreu2.

* fix: resolve lint errors in clipboard guard imports

* test: add clipboard failure test for 100% coverage on touched files

* test: add assertion in clipboard failure test and dispose ValueNotifier
2026-02-13 15:09:44 +01:00