Skip to content

Mutations and performance improvements#3122

Merged
feruzm merged 30 commits intodevelopmentfrom
migrat
Feb 24, 2026
Merged

Mutations and performance improvements#3122
feruzm merged 30 commits intodevelopmentfrom
migrat

Conversation

@feruzm
Copy link
Copy Markdown
Member

@feruzm feruzm commented Feb 22, 2026

Summary by CodeRabbit

  • New Features

    • Mutation-backed actions for follow/unfollow, subscribe/leave, reblog, pin, transfers (multiple layers), boosts/claims, posting-permission grants, and optimistic comment updates.
    • Shared minute ticker for fresher relative timestamps.
  • Improvements

    • Unified transfer and tipping flows with improved amount formatting.
    • Faster, more consistent UI via query-cache syncing, optimistic updates, and clearer success/error toasts.
    • More reliable notification marking and vote-state propagation; safer profile navigation.
  • Bug Fixes

    • Corrected tab visibility checks and loading/empty-state behaviors.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

Replaces many direct dhive/pin/private-key and Redux-thunk flows with auth-aware @ecency/sdk mutation hooks, removes Redux vote-cache injection in favor of TanStack Query cache updates, adds shared hooks (minute ticker, follow/subscription, transfer mutations), and introduces optimistic comment and vote-cache utilities.

Changes

Cohort / File(s) Summary
SDK mutation wrappers & exports
src/providers/sdk/mutations/*.ts, src/providers/sdk/mutations/index.ts, src/providers/sdk/index.ts, src/providers/sdk/mutations/common.ts
Adds ~40+ thin auth-wired mutation hooks, useMutationAuth, and a central re-export to surface SDK mutation hooks.
Query cache & vote utilities
src/providers/queries/postQueries/voteCacheUtils.ts, src/providers/queries/postQueries/postQueries.ts, src/utils/postParser.tsx
Removes Redux vote-cache injection; adds VoteCacheEntry and updateVoteInQueryCaches to update TanStack Query caches; simplifies vote parsing helpers.
Follow / subscription flows & UI
src/hooks/useFollowUserAction.ts, src/hooks/useCommunitySubscriptionAction.ts, src/components/organisms/quickProfileModal/.../quickProfileContent.tsx, src/containers/profileContainer.tsx, src/screens/.../community*.ts*
Replaces thunk-based follow/subscribe with useFollowMutation/useUnfollowMutation and community subscription hooks; components call mutation-backed handlers; renames favourites→favorites imports/keys.
Transfers, wallet, redeem & boosts
src/hooks/useTransferMutations.ts, src/containers/transferContainer.ts, src/containers/walletContainer.ts, src/containers/redeemContainer.ts, src/containers/pointsContainer.ts
Converts transfer/boost/redeem/claim flows to mutation-driven APIs via aggregated transfer mutations; removes executeOperation/private-key/pinCode flows and standardizes error handling.
Posting, reblog & posting authority
src/components/postOptionsModal/.../postOptionsModal.tsx, src/components/postingAuthoritySheet/postingAuthoritySheet.tsx, src/screens/editor/.../editorContainer.tsx, src/providers/queries/postQueries/repostQueries.ts
Moves reblog/pin/grant-posting to SDK mutations, adds optimistic update patterns, and delegates posting-authority routing to mutation wrappers.
Optimistic comments & comment cache helpers
src/components/quickPostModal/usePostSubmitter.ts, src/providers/queries/postQueries/commentQueries.ts
Adds addOptimisticComment / removeOptimisticComment, integrates optimistic insertion/rollback into comment mutation flows, and updates root/parent children counts in query cache.
Waves / feed & queries
src/providers/queries/postQueries/wavesQueries.ts, src/providers/queries/queryKeys.ts, src/providers/sdk/mobilePlatformAdapter.ts
Refactors waves to host-scoped infinite queries, removes legacy WAVES query keys and cross-query invalidation, and adds publish/delete host-scoped mutation surfaces.
Notifications & polls
src/providers/queries/notificationQueries.ts, src/providers/queries/postQueries/pollQueries.ts
Switches notification marking and poll voting to useBroadcastMutation with auth context; adjusts mutation lifecycles and return shapes.
Tips & tipping formatting
src/providers/queries/postQueries/tipsQueries.ts, src/services/tippingService.ts
Splits tipping into currency-aware transfer mutations; adds TipParams/formatting helpers and removes legacy sendTip.
Shared hooks & utilities
src/hooks/*, src/hooks/index.ts, src/hooks/useMinuteTicker.ts
Adds useMinuteTicker, useFollowUserAction, useCommunitySubscriptionAction, useTransferMutations and re-exports them.
Redux & selectors cleanup
src/redux/actions/cacheActions.ts, src/redux/actions/communitiesAction.ts, src/redux/actions/userAction.ts, src/redux/reducers/cacheReducer.ts, src/redux/selectors/index.ts
Removes vote-cache action/creators/selectors and community follow thunks; adapts reducers and action payloads to new query-driven flows.
Misc UI / small refactors
src/components/postCard/..., src/components/postView/..., src/components/comment/..., src/components/hiveAuthModal/hooks/useHiveAuth.ts, src/components/hiveAuthBroadcastSheet/hiveAuthBroadcastSheet.tsx
Various UI updates: minute ticker, profile navigation handlers, broadcast in‑progress tracking, UI simplifications (dropdown→text), and safety guards.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Component (e.g., QuickProfile)
  participant Hook as useFollowUserAction
  participant SDK as `@ecency/sdk` (mutation)
  participant QC as QueryClient
  participant Redux as Redux (optimistic actions/toasts)

  UI->>Hook: handleFollowUser({ following })
  Hook->>Redux: dispatch FOLLOW (optimistic)
  Hook->>SDK: mutateAsync({ following })
  SDK-->>Hook: success / error
  alt success
    Hook->>Redux: dispatch FOLLOW_SUCCESS
    Hook->>QC: invalidate/refetch affected queries
    Hook->>Redux: dispatch TOAST_NOTIFICATION (success)
  else error
    Hook->>Redux: dispatch FOLLOW_FAIL
    Hook->>Redux: dispatch TOAST_NOTIFICATION (failure)
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐰 I hopped through hooks and nibbled thunks away,
Mutations hum where PINs used to stay.
Optimistic carrots tucked into the cache,
Queries bloom fresh — I twitch my whiskered sash.
Hooray, I hop: the app feels lighter today!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.21% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Mutations and performance improvements' directly reflects the main changes in the PR, which include extensive SDK mutation adoption and various performance optimizations such as shared ticker hooks, query cache improvements, and removal of redundant cache injection logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch migrat

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (3)
src/components/hiveAuthModal/hooks/useHiveAuth.ts (2)

435-445: PIN and pinCode validation is thorough.

Both the raw pin and the derived pinCode are validated before use in decryption, addressing the previously identified concern about getDigitPinCode returning undefined.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts` around lines 435 - 445,
The PIN and derived pinCode are both validated in useHiveAuth: ensure the
pre-decryption checks remain intact by keeping the existing guards that throw
errors when pin is falsy or when getDigitPinCode(pin) returns a falsy value;
specifically, retain the two checks around pin and pinCode (the call to
getDigitPinCode and the two throws using intl.formatMessage) so decryption never
runs with an undefined pinCode.

399-413: Broadcast-in-progress flag and ref-based reads look correct.

The didIncrementBroadcastInProgress local flag properly addresses the previously identified race condition where _broadcastInProgressCount could be decremented in finally without ever being incremented. Reading account and pin from refs at the top of broadcast is the right approach.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts` around lines 399 - 413, No
code changes required: the broadcast function correctly uses a local
didIncrementBroadcastInProgress flag to avoid decrementing
_broadcastInProgressCount when it was never incremented, and it reads fresh
values from refs (currentAccountRef and pinHashRef) to avoid stale closures;
keep the current logic in broadcast, including the assert and the account/pin
ref reads and the _broadcastInProgressCount increment/decrement guard.
src/providers/queries/notificationQueries.ts (1)

78-83: ⚠️ Potential issue | 🟠 Major

Invalidate filtered notification caches consistently.

notificationsQueryKey is built with filter = undefined at Lines 78–83. If any screens call useNotificationsQuery with a non-undefined filter, those caches won’t be invalidated after mark‑read, leaving stale filtered lists. Consider threading the active filter into this hook or invalidating by a broader base key/predicate.

✅ One possible fix (requires updating call sites)
-export const useNotificationReadMutation = () => {
+export const useNotificationReadMutation = (filter?: NotificationFilters) => {
   ...
-  const notificationsQueryKey = getNotificationsInfiniteQueryOptions(
-    username,
-    authCode,
-    undefined,
-    FETCH_LIMIT,
-  ).queryKey;
+  const notificationsQueryKey = getNotificationsInfiniteQueryOptions(
+    username,
+    authCode,
+    filter,
+    FETCH_LIMIT,
+  ).queryKey;

To verify filtered usage:

#!/bin/bash
# Find all useNotificationsQuery call sites and check if a filter is passed
rg -n "useNotificationsQuery\\s*\\(" -C2 src
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/providers/queries/notificationQueries.ts` around lines 78 - 83,
notificationsQueryKey is being built with filter = undefined (using
getNotificationsInfiniteQueryOptions) so invalidate calls won't match caches
created by useNotificationsQuery when a filter is provided; update the
invalidation to include the active filter or use a broader predicate: either (A)
accept a filter param in this module/hook and build notificationsQueryKey via
getNotificationsInfiniteQueryOptions(username, authCode, filter, FETCH_LIMIT) so
invalidation targets the exact filtered key (refer to notificationsQueryKey and
getNotificationsInfiniteQueryOptions), or (B) call queryClient.invalidateQueries
with a predicate/partial key that matches the base notifications key (e.g., the
same queryKey[0]/base key returned by getNotificationsInfiniteQueryOptions) so
all filtered variants created by useNotificationsQuery are invalidated after
mark-read. Ensure you update callers of notifications invalidation or the hook
signature accordingly (see useNotificationsQuery for where filters originate).
🧹 Nitpick comments (2)
src/components/hiveAuthModal/hooks/useHiveAuth.ts (1)

650-653: The Math.max(0, ...) is now redundant with the didIncrementBroadcastInProgress guard.

With the flag ensuring we only decrement when we actually incremented, the counter can never go below zero from this path. The Math.max is harmless defensive coding—fine to keep, but a plain _broadcastInProgressCount-- would be equivalent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts` around lines 650 - 653,
The finally block currently decrements _broadcastInProgressCount using
Math.max(0, _broadcastInProgressCount - 1) despite already guarding with the
didIncrementBroadcastInProgress flag; replace that defensive expression with a
simple decrement to reflect the guard — update the finally clause where
didIncrementBroadcastInProgress is checked so it does
_broadcastInProgressCount-- (or equivalent) instead of Math.max(...) to simplify
the logic around _broadcastInProgressCount.
src/components/promote/promoteView.tsx (1)

110-110: _renderDropdown name no longer reflects its implementation.

The function only renders a <Text> label now; the "Dropdown" name is a leftover that could confuse future readers.

✏️ Suggested rename
-  const _renderDropdown = (accountName) => <Text style={styles.dropdownText}>{accountName}</Text>;
+  const _renderAccountLabel = (accountName) => <Text style={styles.dropdownText}>{accountName}</Text>;
-              rightComponent={() => _renderDropdown(currentAccountName)}
+              rightComponent={() => _renderAccountLabel(currentAccountName)}

Also applies to: 128-128

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/promote/promoteView.tsx` at line 110, The helper
_renderDropdown no longer renders a dropdown and should be renamed to reflect
its behavior (e.g., _renderAccountLabel or renderAccountText); update the
function declaration and all uses of _renderDropdown (and the similar occurrence
around line 128) to the new name, keeping the implementation unchanged
(returning <Text style={styles.dropdownText}>{accountName}</Text>) and ensure
imports/exports or references in the component match the new identifier.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts`:
- Around line 588-607: In useHiveAuth, before applying the re-auth credentials
from auth to the account read from currentAccountRef (freshAccount), validate
that freshAccount.name === username (the username captured earlier) and skip the
Redux update if they differ; if mismatched, log a clear warning including both
names and do not call updateCurrentAccount, otherwise proceed with building
updatedLocal (encrypting auth.token with pinCode and setting hiveAuthExpiry) and
dispatching updateCurrentAccount as currently implemented.
- Around line 507-515: The callback that calls
getHiveAuthUri/extractPreferredScheme can return early on error but leaves
HAS.broadcast/_cdWait awaiting a response and keeps _broadcastInProgressCount
elevated; modify the callback used with HAS.broadcast so that when
getHiveAuthUri fails or returns null you immediately abort the broadcast (use an
AbortController or invoke the broadcast's reject path) before calling
setStatusText/setStatus to ensure _broadcastInProgressCount is decremented and
_cdWait does not hang; locate the logic around getHiveAuthUri,
extractPreferredScheme, setStatusText, setStatus and integrate an abort signal
or local timeout wrapper that triggers broadcast cancellation when the signing
app cannot be opened.

In `@src/providers/queries/notificationQueries.ts`:
- Around line 75-76: The useMemo call memoizing getDigitPinCode(pinHash) must
guard against a missing pinHash to avoid decryptKey being called with undefined;
update the useMemo in notificationQueries.ts so it returns null/undefined
(consistent with useAuth.ts and useClaimPointsMutation.ts) when pinHash is
falsy, and only invoke getDigitPinCode(pinHash) when pinHash is truthy; ensure
callers of the memoized value handle the nullable result.

In `@src/providers/queries/postQueries/tipsQueries.ts`:
- Around line 59-113: Before performing transfers in the mutationFn inside
useMutation (TipParams handler), add guards to validate recipient, author, and
permlink: trim each value and ensure they are non-empty strings, throwing a
clear Error (e.g., "Tip recipient is required", "Tip author is required", "Tip
permlink is required") if any are invalid; also ensure recipient matches
expected address format if applicable, and use the validated/sanitized author
and permlink when building the memo variable and when calling
transferPointMutation.mutateAsync, transferMutation.mutateAsync, and
transferEngineMutation.mutateAsync to avoid malformed memos or invalid
transfers.

---

Duplicate comments:
In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts`:
- Around line 435-445: The PIN and derived pinCode are both validated in
useHiveAuth: ensure the pre-decryption checks remain intact by keeping the
existing guards that throw errors when pin is falsy or when getDigitPinCode(pin)
returns a falsy value; specifically, retain the two checks around pin and
pinCode (the call to getDigitPinCode and the two throws using
intl.formatMessage) so decryption never runs with an undefined pinCode.
- Around line 399-413: No code changes required: the broadcast function
correctly uses a local didIncrementBroadcastInProgress flag to avoid
decrementing _broadcastInProgressCount when it was never incremented, and it
reads fresh values from refs (currentAccountRef and pinHashRef) to avoid stale
closures; keep the current logic in broadcast, including the assert and the
account/pin ref reads and the _broadcastInProgressCount increment/decrement
guard.

In `@src/providers/queries/notificationQueries.ts`:
- Around line 78-83: notificationsQueryKey is being built with filter =
undefined (using getNotificationsInfiniteQueryOptions) so invalidate calls won't
match caches created by useNotificationsQuery when a filter is provided; update
the invalidation to include the active filter or use a broader predicate: either
(A) accept a filter param in this module/hook and build notificationsQueryKey
via getNotificationsInfiniteQueryOptions(username, authCode, filter,
FETCH_LIMIT) so invalidation targets the exact filtered key (refer to
notificationsQueryKey and getNotificationsInfiniteQueryOptions), or (B) call
queryClient.invalidateQueries with a predicate/partial key that matches the base
notifications key (e.g., the same queryKey[0]/base key returned by
getNotificationsInfiniteQueryOptions) so all filtered variants created by
useNotificationsQuery are invalidated after mark-read. Ensure you update callers
of notifications invalidation or the hook signature accordingly (see
useNotificationsQuery for where filters originate).

---

Nitpick comments:
In `@src/components/hiveAuthModal/hooks/useHiveAuth.ts`:
- Around line 650-653: The finally block currently decrements
_broadcastInProgressCount using Math.max(0, _broadcastInProgressCount - 1)
despite already guarding with the didIncrementBroadcastInProgress flag; replace
that defensive expression with a simple decrement to reflect the guard — update
the finally clause where didIncrementBroadcastInProgress is checked so it does
_broadcastInProgressCount-- (or equivalent) instead of Math.max(...) to simplify
the logic around _broadcastInProgressCount.

In `@src/components/promote/promoteView.tsx`:
- Line 110: The helper _renderDropdown no longer renders a dropdown and should
be renamed to reflect its behavior (e.g., _renderAccountLabel or
renderAccountText); update the function declaration and all uses of
_renderDropdown (and the similar occurrence around line 128) to the new name,
keeping the implementation unchanged (returning <Text
style={styles.dropdownText}>{accountName}</Text>) and ensure imports/exports or
references in the component match the new identifier.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e17ce8 and 25da12a.

📒 Files selected for processing (8)
  • src/components/hiveAuthModal/hooks/useHiveAuth.ts
  • src/components/organisms/quickProfileModal/children/quickProfileContent.tsx
  • src/components/organisms/quickProfileModal/container/quickProfileModal.tsx
  • src/components/promote/promoteView.tsx
  • src/containers/pointsContainer.ts
  • src/providers/queries/notificationQueries.ts
  • src/providers/queries/postQueries/tipsQueries.ts
  • src/screens/searchResult/screen/tabs/communities/container/communitiesResultsContainer.ts

Comment thread src/components/hiveAuthModal/hooks/useHiveAuth.ts
Comment thread src/components/hiveAuthModal/hooks/useHiveAuth.ts
Comment thread src/providers/queries/notificationQueries.ts Outdated
Comment thread src/providers/queries/postQueries/tipsQueries.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant