Skip to content

feature: PR 5/8 — React Feed, Item, Loader and ErrorMessage - #702

Open
devin-ai-integration[bot] wants to merge 1 commit into
devin/react-migration-04-routing-shellfrom
devin/react-migration-05-feed
Open

feature: PR 5/8 — React Feed, Item, Loader and ErrorMessage#702
devin-ai-integration[bot] wants to merge 1 commit into
devin/react-migration-04-routing-shellfrom
devin/react-migration-05-feed

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 26, 2026

Copy link
Copy Markdown

Summary

PR 5 of the Angular→React migration: the feed feature. Feed becomes a real component fetching from the PR 2 API layer, plus presentational Item, Loader and ErrorMessage ports. Nothing under src/app/ changes; Angular still builds as before.

FeedComponent's two route subscriptions collapse into one effect keyed on the feed and page, with a stale-response guard replacing the implicit per-navigation subscription:

useEffect(() => {
  let ignore = false;
  setErrorMessage('');
  fetchFeed(feedName, pageNum)
    .then(next => { if (ignore) return; setItems(next); setListStart((pageNum - 1) * 30 + 1); window.scrollTo(0, 0); })
    .catch(() => { if (ignore) return; setErrorMessage('Could not load ' + feedName + ' stories.'); });
  return () => { ignore = true; };
}, [feedName, pageNum]);

Parity details worth knowing:

  • items is deliberately not cleared on route change, matching Angular — the previous page stays on screen while the next loads, so Loader only appears on first load.
  • One intentional deviation: errorMessage is reset at the start of each fetch. Angular never reset it, so a single failure left the error banner set for the rest of the session.
  • Angular's *ngIf="feedType !== 'new'" on the <ol> was unreachable (no feed is named new), so the list renders unconditionally.
  • hasUrl is item.url?.indexOf('http') === 0. Some jobs items have no url at all, where the Angular getter would have thrown; those now correctly render as internal /item/:id links.
  • External title links get target/rel only when openLinkInNewTab is set — undefined, so the attributes are absent rather than empty, matching Angular's [attr.target]="… : null".
  • Loader also replaces the temporary inline <div>Loading…</div> Suspense fallback added in PR 4.

The four ported SCSS files are byte-identical to the Angular originals apart from @import paths.

Verification

npm run typecheck:react and npx vite build pass. In the dev server: /news/1 renders 30 real stories with More › and no Prev; /news/2 renders <ol start="31"> with both nav links; /jobs/1 shows the jobs blurb and job items without points or comment links. Console clean.

/news/1:

news feed page 1

/news/2 (list starts at 31, both nav links):

news feed page 2

/jobs/1 (jobs blurb, no points/comments):

jobs feed

Devin-Org: engineering

Link to Devin session: https://app.devin.ai/sessions/e6419ebe67ff4f749fe1573a8e26cd07
Requested by: @abboudp


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Devin Review (Staging)

Co-Authored-By: Paul Abboud <abboudpaul112@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

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.

0 participants