Skip to content

fix(newsletter): profile subscriber row layout and first-class Email digest action - #3523

Merged
feruzm merged 3 commits into
developmentfrom
fix/profile-sender-row-height
Aug 27, 2026
Merged

fix(newsletter): profile subscriber row layout and first-class Email digest action#3523
feruzm merged 3 commits into
developmentfrom
fix/profile-sender-row-height

Conversation

@feruzm

@feruzm feruzm commented Aug 25, 2026

Copy link
Copy Markdown
Member

Closes #3522. Closes #3524. Two profile newsletter UX fixes from owner testing.

Subscriber row clipped by the summary card (#3522)

The own-profile subscriber row rendered inside the profile summary CollapsibleCard, which measures its content ONCE on first layout; the row appears only after the sender query resolves, so it was clipped under the tab bar. A first attempt reserved a fixed height through the card's moreHeight channel; review correctly killed it (28pt reservation smaller than the row's own 30pt icon, breaks under font scaling, double-counts when cached data renders before measurement). Final design: the row lives as a SIBLING below the card in normal layout flow with natural height, no height arithmetic at all, hidden together with the collapsed summary via isSummaryOpen. Small-device hardening: single-line shrinking count text, single-line max-width Manage label.

Email digest as a first-class profile action (#3524)

The website's mobile layout shows Email digest in the profile action row; the app buried it in the ••• dropdown. Now an envelope icon button sits next to Message (accessibility-labeled, disabled while the profile loads) opening the digest sheet, and the dropdown entry is removed so the action lives in one place.

Verification: yarn typecheck 0 errors (empty baseline), yarn lint 0 errors, full jest suite 927 passed.

…y card's height channel

The profile summary CollapsibleCard measures its content once on first
layout; the subscriber row appears only after the sender query resolves,
so it grew the content past the measured height and was clipped under the
tab bar. The row now has a fixed height and reports its visibility to
ProfileSummaryView, which combines it with the VP/RC bars toggle into the
ONE moreHeight value the card accepts (the channel is single-valued, so
two direct writers would overwrite each other). The count text is single
line and shrinks on narrow devices. Closes #3522
@qodo-code-review

Copy link
Copy Markdown

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@qodo-code-review

qodo-code-review Bot commented Aug 25, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Prevent profile subscriber row clipping in summary cards

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Prevents asynchronously loaded subscriber details from being clipped in fixed-height profile
 summaries.
• Combines subscriber and power-bar adjustments through the card’s single height channel.
• Keeps subscriber actions visible on narrow screens with shrinkable single-line count text.
Diagram

graph TD
  Q["Sender Query"] --> N["Subscriber Row"] --> S["Height Combiner"] --> P["Profile State"] --> C["Collapsible Card"]
  B["VP RC Bars"] --> S
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Remeasure dynamic card content
  • ➕ Handles future asynchronous content without fixed exported heights
  • ➕ Centralizes dynamic sizing inside CollapsibleCard
  • ➖ Broadens a targeted bug fix into shared component behavior
  • ➖ May introduce animation or layout feedback across existing card consumers
  • ➖ Requires wider regression coverage

Recommendation: Keep the PR’s localized combiner because it follows the existing moreHeight contract and avoids destabilizing a shared animated component. Consider dynamic remeasurement separately if more asynchronously rendered summary sections are added.

Files changed (3) +55 / -10

Bug fix (3) +55 / -10
index.tsExport the subscriber row height contract +1/-0

Export the subscriber row height contract

• Re-exports the fixed sender-information row height so the profile summary can include it in the card’s extra-height calculation.

src/components/newsletterSenderInfo/index.ts

newsletterSenderInfo.tsxReport subscriber row visibility and enforce stable sizing +24/-4

Report subscriber row visibility and enforce stable sizing

• Defines a fixed 28-pixel row height and notifies the parent when asynchronous subscriber data makes the row visible or hidden, including unmount cleanup. Constrains the count to one shrinkable line so the link and Manage actions remain accessible on narrow screens.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx

profileSummaryView.tsxCombine subscriber and power-bar height adjustments +30/-6

Combine subscriber and power-bar height adjustments

• Tracks subscriber-row visibility and combines its fixed height with the existing expanded VP/RC bar allowance before reporting through handleUIChange. Routes both dynamic height consumers through one calculation so they cannot overwrite each other.

src/components/profileSummary/view/profileSummaryView.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a71bea7d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const { isShowPercentText, senderInfoVisible } = this.state;
if (handleUIChange) {
handleUIChange(
(isShowPercentText ? 30 : 0) + (senderInfoVisible ? NEWSLETTER_SENDER_INFO_HEIGHT : 0),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid double-counting an initially cached sender row

When the own profile is popped and reopened while the sender query remains in the in-memory cache, NewsletterSenderInfo renders its 28-point row during the card's initial layout, so CollapsibleCard already includes that row in contentHeight. The visibility effect then sets senderInfoVisible, and this expression adds the same 28 points again, leaving an extra blank row beneath the summary on repeat visits; only report the delta when the row appeared after the initial measurement, or make the card remeasure its content.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c45ed63 by removing the arithmetic entirely: the row moved OUT of the CollapsibleCard and renders as a sibling below it in normal layout flow, so nothing is ever added to moreHeight and a cached first render cannot be counted twice. It follows isSummaryOpen, so collapsing the summary hides it too.


const styles = EStyleSheet.create({
row: {
height: NEWSLETTER_SENDER_INFO_HEIGHT,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Account for scaled text in the reported row height

With accessibility font scaling enabled, the subscriber count and Manage label can exceed this fixed 28-point height (and the existing IconButton is already 30 points tall). Because the collapsible card is also told to reserve exactly 28 points, large text is clipped or overlaps the following bars; use a measured/minimum height or otherwise include the scaled content's actual height.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c45ed63: the fixed height is gone. As a sibling outside the measured card the row takes its natural height, so scaled text and the 30pt icon simply make it taller instead of clipping.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 25, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Row shorter than icon ✓ Resolved 📎 Requirement gap ≡ Correctness
Description
NEWSLETTER_SENDER_INFO_HEIGHT fixes the row at 28px, but its IconButton child is fixed at
30×30px. The row therefore does not fully accommodate its own content and can still clip or overlap
vertically.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[88]

+    height: NEWSLETTER_SENDER_INFO_HEIGHT,
Evidence
Rule 1 requires the fixed-height row to be fully accommodated. The PR sets the row height to 28,
while the shared IconButton used in that row has a fixed width and height of 30.

Prevent clipping of the own-profile subscriber row
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-78]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[87-93]
src/components/iconButton/view/iconButtonStyles.ts[3-10]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The fixed subscriber row is 28px high while its link `IconButton` is 30px high, so the row does not fully contain its content.
## Issue Context
Compliance rule 1 requires the asynchronously displayed row to be fully accommodated and not clipped. Increase the exported fixed height or reduce the child size, and keep the reported `moreHeight` synchronized through the shared constant.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-78]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[87-93]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Manage width remains unconstrained ✓ Resolved 📎 Requirement gap ≡ Correctness
Description
The PR makes the count text shrink, but the Manage action still has no fixed-width container or
width constraint. A long localized action label can therefore consume or exceed the available row
width on small devices, contrary to the required fixed action area.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[95]

+    flexShrink: 1,
Evidence
Rule 1 explicitly requires fixed icon/action widths on small devices. The branch gives the count
flexShrink: 1, and the shared icon is fixed at 30px, but the TouchableOpacity around Manage
has no style and manageText defines no width or truncation constraint.

Prevent clipping of the own-profile subscriber row
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-81]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[94-103]
src/components/iconButton/view/iconButtonStyles.ts[3-10]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The subscriber count now shrinks, but the `Manage` action remains content-sized rather than occupying a fixed or otherwise bounded action area.
## Issue Context
Compliance rule 1 requires fixed icon and action areas so localized labels cannot push controls off-screen on small devices. Add an explicit bounded wrapper style for the action while preserving a usable single-line label.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[79-81]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[94-103]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Cached row height double-counted ⊘ Outdated 🐞 Bug ≡ Correctness
Description
When sender data is cached, the row is present in the card's one-time initial measurement, but the
visibility effect still adds another 28px through moreHeight. The expanded summary therefore ends
up with 28px of blank space on cached/remounted profile views.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[R48-51]

+  useEffect(() => {
+    onVisibilityChange?.(visible);
+    return () => {
+      onVisibilityChange?.(false);
Relevance

●●● Strong

Accepted history favors concrete async/layout correctness fixes; cached content double-counting is a
specific deterministic bug.

PR-#3521
PR-#3267

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Available subscribers render the fixed-height row immediately, while the new effect reports it as
extra height. CollapsibleCard stores the already-rendered content height once and adds
moreHeight; query data is retained for 30 minutes, so remounting the profile can take this
cache-hit path.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[45-65]
src/components/profileSummary/view/profileSummaryView.tsx[44-57]
src/components/profile/profileView.tsx[217-227]
src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
src/providers/queries/index.ts[19-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sender row is always reported as extra height, even when it was already included in `CollapsibleCard`'s initial content measurement. On a React Query cache hit this double-counts the row and adds 28px of blank space.
## Issue Context
The height adjustment must distinguish content that appears after the card's baseline measurement from content present during that measurement, or the card must track the inner content's natural height directly.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[48-53]
- src/components/profileSummary/view/profileSummaryView.tsx[44-57]
- src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Row shorter than child ✓ Resolved 🐞 Bug ≡ Correctness
Description
The row is fixed at 28px even though its IconButton child has a fixed 30px height. The touchable
therefore overflows the reported row bounds and can overlap adjacent summary content rather than
fitting within the space reserved by the card.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[88]

+    height: NEWSLETTER_SENDER_INFO_HEIGHT,
Relevance

●●● Strong

Concrete parent-child sizing overflow matches accepted layout and touch-target corrections in recent
reviews.

PR-#3423
PR-#3203

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newsletter row centers an IconButton inside its new fixed 28px height, but the shared
IconButton style fixes its touchable at 30×30. The profile combiner reserves exactly the exported
28px, confirming that no additional space covers the overflow.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-93]
src/components/iconButton/view/iconButtonStyles.ts[4-10]
src/components/profileSummary/view/profileSummaryView.tsx[44-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fixed row height is 28px, but the rendered `IconButton` is 30px tall, so the row's actual child does not fit in the height reported to the card.
## Issue Context
Keep the exported reserved height and rendered row dimensions consistent, and ensure the value is at least the fixed height of every child.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-88]
- src/components/iconButton/view/iconButtonStyles.ts[4-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Row shorter than child ✓ Resolved 🐞 Bug ≡ Correctness
Description
The row is fixed at 28px even though its IconButton child has a fixed 30px height. The touchable
therefore overflows the reported row bounds and can overlap adjacent summary content rather than
fitting within the space reserved by the card.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[88]

+    height: NEWSLETTER_SENDER_INFO_HEIGHT,
Relevance

●●● Strong

Concrete parent-child sizing overflow matches accepted layout and touch-target corrections in recent
reviews.

PR-#3423
PR-#3203

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newsletter row centers an IconButton inside its new fixed 28px height, but the shared
IconButton style fixes its touchable at 30×30. The profile combiner reserves exactly the exported
28px, confirming that no additional space covers the overflow.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-93]
src/components/iconButton/view/iconButtonStyles.ts[4-10]
src/components/profileSummary/view/profileSummaryView.tsx[44-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fixed row height is 28px, but the rendered `IconButton` is 30px tall, so the row's actual child does not fit in the height reported to the card.
## Issue Context
Keep the exported reserved height and rendered row dimensions consistent, and ensure the value is at least the fixed height of every child.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-88]
- src/components/iconButton/view/iconButtonStyles.ts[4-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View medium (4)
6. Cached row height double-counted ⊘ Outdated 🐞 Bug ≡ Correctness
Description
When sender data is cached, the row is present in the card's one-time initial measurement, but the
visibility effect still adds another 28px through moreHeight. The expanded summary therefore ends
up with 28px of blank space on cached/remounted profile views.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[R48-51]

+  useEffect(() => {
+    onVisibilityChange?.(visible);
+    return () => {
+      onVisibilityChange?.(false);
Relevance

●●● Strong

Accepted history favors concrete async/layout correctness fixes; cached content double-counting is a
specific deterministic bug.

PR-#3521
PR-#3267

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Available subscribers render the fixed-height row immediately, while the new effect reports it as
extra height. CollapsibleCard stores the already-rendered content height once and adds
moreHeight; query data is retained for 30 minutes, so remounting the profile can take this
cache-hit path.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[45-65]
src/components/profileSummary/view/profileSummaryView.tsx[44-57]
src/components/profile/profileView.tsx[217-227]
src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
src/providers/queries/index.ts[19-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sender row is always reported as extra height, even when it was already included in `CollapsibleCard`'s initial content measurement. On a React Query cache hit this double-counts the row and adds 28px of blank space.
## Issue Context
The height adjustment must distinguish content that appears after the card's baseline measurement from content present during that measurement, or the card must track the inner content's natural height directly.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[48-53]
- src/components/profileSummary/view/profileSummaryView.tsx[44-57]
- src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Row shorter than child ✓ Resolved 🐞 Bug ≡ Correctness
Description
The row is fixed at 28px even though its IconButton child has a fixed 30px height. The touchable
therefore overflows the reported row bounds and can overlap adjacent summary content rather than
fitting within the space reserved by the card.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[88]

+    height: NEWSLETTER_SENDER_INFO_HEIGHT,
Relevance

●●● Strong

Concrete parent-child sizing overflow matches accepted layout and touch-target corrections in recent
reviews.

PR-#3423
PR-#3203

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newsletter row centers an IconButton inside its new fixed 28px height, but the shared
IconButton style fixes its touchable at 30×30. The profile combiner reserves exactly the exported
28px, confirming that no additional space covers the overflow.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-93]
src/components/iconButton/view/iconButtonStyles.ts[4-10]
src/components/profileSummary/view/profileSummaryView.tsx[44-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fixed row height is 28px, but the rendered `IconButton` is 30px tall, so the row's actual child does not fit in the height reported to the card.
## Issue Context
Keep the exported reserved height and rendered row dimensions consistent, and ensure the value is at least the fixed height of every child.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-88]
- src/components/iconButton/view/iconButtonStyles.ts[4-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Cached row height double-counted ⊘ Outdated 🐞 Bug ≡ Correctness
Description
When sender data is cached, the row is present in the card's one-time initial measurement, but the
visibility effect still adds another 28px through moreHeight. The expanded summary therefore ends
up with 28px of blank space on cached/remounted profile views.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[R48-51]

+  useEffect(() => {
+    onVisibilityChange?.(visible);
+    return () => {
+      onVisibilityChange?.(false);
Relevance

●●● Strong

Accepted history favors concrete async/layout correctness fixes; cached content double-counting is a
specific deterministic bug.

PR-#3521
PR-#3267

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Available subscribers render the fixed-height row immediately, while the new effect reports it as
extra height. CollapsibleCard stores the already-rendered content height once and adds
moreHeight; query data is retained for 30 minutes, so remounting the profile can take this
cache-hit path.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[45-65]
src/components/profileSummary/view/profileSummaryView.tsx[44-57]
src/components/profile/profileView.tsx[217-227]
src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
src/providers/queries/index.ts[19-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sender row is always reported as extra height, even when it was already included in `CollapsibleCard`'s initial content measurement. On a React Query cache hit this double-counts the row and adds 28px of blank space.
## Issue Context
The height adjustment must distinguish content that appears after the card's baseline measurement from content present during that measurement, or the card must track the inner content's natural height directly.
## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[48-53]
- src/components/profileSummary/view/profileSummaryView.tsx[44-57]
- src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Cached row height double-counted ⊘ Outdated 🐞 Bug ≡ Correctness
Description
_reportMoreHeight always adds 28 points when sender data is visible, even if cached data rendered
the row before CollapsibleCard made its one-time natural-height measurement. On a repeat profile
visit within the query cache window, the measured height already includes the row and the card then
adds another 28 points, leaving an oversized summary card.
Code

src/components/profileSummary/view/profileSummaryView.tsx[R48-50]

+      handleUIChange(
+        (isShowPercentText ? 30 : 0) + (senderInfoVisible ? NEWSLETTER_SENDER_INFO_HEIGHT : 0),
+      );
Evidence
The sender row renders immediately whenever query data contains subscribers, while the query
client retains results for 30 minutes. CollapsibleCard measures its children once and later
computes its expanded height as that measured value plus moreHeight; therefore, when cached data
puts the row in the first measurement, the new visibility callback and combiner add the same fixed
row height a second time.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[41-56]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-89]
src/components/profileSummary/view/profileSummaryView.tsx[44-57]
src/components/profileSummary/view/profileSummaryView.tsx[339-352]
src/components/collapsibleCard/view/collapsibleCardView.tsx[31-35]
src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
src/providers/queries/index.ts[19-25]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Cached newsletter sender data can render during the card's initial layout, so the row is included in the natural measured height and then added again through `moreHeight`.
## Issue Context
The query cache retains data for 30 minutes. The fix must distinguish content present during the initial card measurement from content that appears after that measurement, while continuing to combine the bars and sender-row deltas through one channel.
## Fix Focus Areas
- src/components/profileSummary/view/profileSummaryView.tsx[44-57]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[45-53]
- src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
Add coverage for both an unresolved initial query that later shows the row and cached sender data visible on the first render.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo


const styles = EStyleSheet.create({
row: {
height: NEWSLETTER_SENDER_INFO_HEIGHT,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Row shorter than icon 📎 Requirement gap ≡ Correctness

NEWSLETTER_SENDER_INFO_HEIGHT fixes the row at 28px, but its IconButton child is fixed at
30×30px. The row therefore does not fully accommodate its own content and can still clip or overlap
vertically.
Agent Prompt
## Issue description
The fixed subscriber row is 28px high while its link `IconButton` is 30px high, so the row does not fully contain its content.

## Issue Context
Compliance rule 1 requires the asynchronously displayed row to be fully accommodated and not clipped. Increase the exported fixed height or reduce the child size, and keep the reported `moreHeight` synchronized through the shared constant.

## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-78]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[87-93]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c45ed63: no fixed row height any more; the row sits outside the measured card in normal flow and its natural height contains the 30pt icon.

paddingTop: 6,
},
countText: {
flexShrink: 1,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. manage width remains unconstrained 📎 Requirement gap ≡ Correctness

The PR makes the count text shrink, but the Manage action still has no fixed-width container or
width constraint. A long localized action label can therefore consume or exceed the available row
width on small devices, contrary to the required fixed action area.
Agent Prompt
## Issue description
The subscriber count now shrinks, but the `Manage` action remains content-sized rather than occupying a fixed or otherwise bounded action area.

## Issue Context
Compliance rule 1 requires fixed icon and action areas so localized labels cannot push controls off-screen on small devices. Add an explicit bounded wrapper style for the action while preserving a usable single-line label.

## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[79-81]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[94-103]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in c45ed63: the Manage label is single line with maxWidth 120, and the count text keeps flexShrink with one line, so a long localized action cannot push the row content off narrow screens.

Comment thread src/components/profileSummary/view/profileSummaryView.tsx Outdated
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9711e60d-db40-4f74-8ac3-bb6f2f44f831

📥 Commits

Reviewing files that changed from the base of the PR and between 1a71bea and c45ed63.

📒 Files selected for processing (3)
  • src/components/newsletterSenderInfo/newsletterSenderInfo.tsx
  • src/components/profile/profileView.tsx
  • src/components/profileSummary/view/profileSummaryView.tsx

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The newsletter sender row now uses natural height and constrained text. ProfileView renders it outside the summary card for qualifying expanded own profiles. ProfileSummaryView no longer tracks sender visibility and reports percentage-bar height changes directly.

Changes

Newsletter sender placement

Layer / File(s) Summary
Sender row layout
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx
The row removes fixed-height and visibility handling. Its text remains on one line, and the layout supports shrinking count text and limited management text width.
Profile summary height coordination
src/components/profileSummary/view/profileSummaryView.tsx
The summary removes newsletter sender rendering and visibility callbacks. Percentage-bar toggles report 30 or 0 directly through handleUIChange.
Profile view integration
src/components/profile/profileView.tsx
ProfileView renders NewsletterSenderInfo beside the summary card when the profile is the logged-in user, has a username, and the summary is expanded.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to c45ed

The change fixes the clipped subscriber row and improves small-device layout behavior; with the reported checks passing, no actionable merge-blocking risk remains.

Poem

A rabbit saw the sender row grow
With padded space below in tow
The card shed height reports from sight
The profile placed the row just right
And tidy lines stayed snug and light

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes address clipping, natural row height, collapsed-summary visibility, and small-device text constraints. However, linked issue #3522 explicitly requires the row to use a fixed height, report… Either implement the linked issue’s specified moreHeight approach with fixed row height and visibility reporting, or update issue #3522 to document and approve the sibling layout as the replacement solution before merging.
✅ Passed checks (4 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The changes remain within scope. They relocate the newsletter sender row, remove obsolete visibility-height handling, and adjust text layout to resolve the linked clipping issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the newsletter subscriber row layout fix and the related Email digest action. It matches the main changes in the pull request and is concise enough for repository history.
Full details: Linked Issues check

Explanation

The changes address clipping, natural row height, collapsed-summary visibility, and small-device text constraints. However, linked issue #3522 explicitly requires the row to use a fixed height, report visibility, and combine its height with the bars toggle through moreHeight. The implementation uses a sibling layout instead.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/profile-sender-row-height

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.

Review round: the fixed 28pt reservation was smaller than the row's own
30pt icon, fought accessibility font scaling and double-counted when
cached data rendered the row before the card's one-shot measurement. The
row now lives as a SIBLING below the CollapsibleCard in normal layout
flow: natural height, no moreHeight arithmetic at all, hidden together
with the collapsed summary. The summary view goes back to the plain bars
toggle and the Manage label is single line with a max width so a long
translation cannot push the actions off narrow screens.
@qodo-code-review

qodo-code-review Bot commented Aug 25, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Row shorter than child ✓ Resolved 🐞 Bug ≡ Correctness
Description
The row is fixed at 28px even though its IconButton child has a fixed 30px height. The touchable
therefore overflows the reported row bounds and can overlap adjacent summary content rather than
fitting within the space reserved by the card.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[88]

+    height: NEWSLETTER_SENDER_INFO_HEIGHT,
Relevance

●●● Strong

Concrete parent-child sizing overflow matches accepted layout and touch-target corrections in recent
reviews.

PR-#3423
PR-#3203

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newsletter row centers an IconButton inside its new fixed 28px height, but the shared
IconButton style fixes its touchable at 30×30. The profile combiner reserves exactly the exported
28px, confirming that no additional space covers the overflow.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[64-93]
src/components/iconButton/view/iconButtonStyles.ts[4-10]
src/components/profileSummary/view/profileSummaryView.tsx[44-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new fixed row height is 28px, but the rendered `IconButton` is 30px tall, so the row's actual child does not fit in the height reported to the card.

## Issue Context
Keep the exported reserved height and rendered row dimensions consistent, and ensure the value is at least the fixed height of every child.

## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[20-20]
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[72-88]
- src/components/iconButton/view/iconButtonStyles.ts[4-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Cached row height double-counted ⊘ Outdated 🐞 Bug ≡ Correctness
Description
When sender data is cached, the row is present in the card's one-time initial measurement, but the
visibility effect still adds another 28px through moreHeight. The expanded summary therefore ends
up with 28px of blank space on cached/remounted profile views.
Code

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[R48-51]

+  useEffect(() => {
+    onVisibilityChange?.(visible);
+    return () => {
+      onVisibilityChange?.(false);
Relevance

●●● Strong

Accepted history favors concrete async/layout correctness fixes; cached content double-counting is a
specific deterministic bug.

PR-#3521
PR-#3267

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Available subscribers render the fixed-height row immediately, while the new effect reports it as
extra height. CollapsibleCard stores the already-rendered content height once and adds
moreHeight; query data is retained for 30 minutes, so remounting the profile can take this
cache-hit path.

src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[45-65]
src/components/profileSummary/view/profileSummaryView.tsx[44-57]
src/components/profile/profileView.tsx[217-227]
src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]
src/providers/queries/index.ts[19-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sender row is always reported as extra height, even when it was already included in `CollapsibleCard`'s initial content measurement. On a React Query cache hit this double-counts the row and adds 28px of blank space.

## Issue Context
The height adjustment must distinguish content that appears after the card's baseline measurement from content present during that measurement, or the card must track the inner content's natural height directly.

## Fix Focus Areas
- src/components/newsletterSenderInfo/newsletterSenderInfo.tsx[48-53]
- src/components/profileSummary/view/profileSummaryView.tsx[44-57]
- src/components/collapsibleCard/view/collapsibleCardView.tsx[48-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 43 rules
✅ Skills: 5 invoked
  add-feature
  add-mutation
  add-query
  add-sheet
  code-review
Review mode: ⚖️ Balanced: This is a localized UI behavior change, but it modifies asynchronous visibility reporting and shared height/state coordination across the summary card, warranting a careful single-pass review.

Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/components/newsletterSenderInfo/newsletterSenderInfo.tsx Outdated
Comment thread src/components/newsletterSenderInfo/newsletterSenderInfo.tsx Outdated
Mirrors the website's mobile layout, where Email digest is a first-class
profile action instead of a menu entry: an envelope icon button sits next
to Message (compact enough for narrow devices, accessibility-labeled) and
the dropdown entry is removed so the action lives in one place. Closes #3524
@feruzm feruzm changed the title fix(newsletter): profile subscriber row clipped by the fixed-height summary card fix(newsletter): profile subscriber row layout and first-class Email digest action Aug 25, 2026
@feruzm
feruzm merged commit 8d9a5fc into development Aug 27, 2026
14 checks passed
@feruzm
feruzm deleted the fix/profile-sender-row-height branch August 27, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Surface the Email digest action on the profile action row like the website Profile subscriber row is clipped by the fixed-height summary card

1 participant