Repository navigation
feature: port feeds (FeedList, FeedItem) to React (Workstream 2) - #918
Conversation
…d tests Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…ormalization) Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Side-by-side parity test: Angular (:4300,
|
2cb63ae
into
devin/1792603540-react-foundation
| if (typeof url !== 'string' || url.indexOf('http') !== 0 || !isSafeHref(url)) return null; | ||
| try { | ||
| const parsed = new URL(url); | ||
| return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? url : null; |
There was a problem hiding this comment.
🟡 Scheme-only story links open app routes
On an HTTPS deployment, externalHref('https:example.com') returns a link the browser resolves inside the app. The base URL makes the browser resolve this scheme-only href differently from the base-free validation, so the story never opens.
Learn more
A story URL with a scheme but no // has different meanings depending on whether the URL parser receives a base. Here new URL(url) accepts https:example.com as https://example.com/, but an anchor on an HTTPS page resolves https:example.com relative to the app's base URL. FeedItem uses the returned string directly as the anchor href. The same mismatch affects http:example.com when the app runs over HTTP.
Example: On https://app.example/news/1, a story with url: 'https:example.com' passes validation as https://example.com/. Clicking its title navigates to https://app.example/example.com instead of the story.
Recommended fix: Return parsed.href for scheme-only or otherwise base-dependent HTTP(S) inputs; preserve the original string only when it resolves to the validated destination from the document base. Add a test covering a scheme-only URL and its rendered anchor destination.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Confirmed. My post-test switch to the raw url (e49378c) let https:example.com through: new URL accepts it, but as an href the browser resolves it relative to the page. Since this PR is merged, the fix is in a follow-up PR on a new branch: externalHref now requires ^https?://, so these fall back to /item/:id. Tests added.
Summary
Ports Angular
feeds/feedandfeeds/itemtoreact-app/src/features/feeds/(Workstream 2 of the React migration; base is the foundation branch from #917). Only files underfeatures/feeds/**change.FeedList(/news|newest|show|ask|jobs/:page)useScrollToTop(${feedType}/${page})first, thenhistory.scrollRestoration = 'manual'while mounted (previous value restored on unmount), so More/Back from the bottom doesn't leave a blank viewport.useFeed(feedType, page):<Loader />while pending;<ErrorMessage message={Could not load ${feedType} stories.} />on error. Invalid pages (abc,0) are errors and make no request.<ol start={(page-1)*30+1}>and.list-marginon every feed except jobs. Jobs also gets the.job-headerTriplebyte paragraph. "‹ Prev" shows whenlistStart !== 1; "More ›" only when the page has exactly 30 items.FeedItemexternalHref(url): external<a>only for a parseable http(s) URL that passesisSafeHref. Anything else (item?id=NAsk/Show posts,javascript:, malformed) becomes<Link to="/item/:id">, like Angular'shasUrlfallback.openLinkInNewTabaddstarget="_blank" rel="noopener noreferrer"..subtext-palm(mobile) and.subtext-laptopvariants, job rows (time only),commentLabelfor the comment links.titleFontSizepx on the two title links only;listSpacingpx as the row'smargin-bottom.Title (domain)with the space inside the title anchor,3 hours ago • N comments,120 points by pg+.item-detailspadding +3 hours ago | N comments, and‹ Prev+ 20px +More ›.SCSS:
FeedList.scssandFeedItem.scssport the Angular files rule for rule, scoped with:where(.main-content.feed)and:where(.item-block)so the theme rules still win. Angular's feeda { font-weight: bold }only ever reached the feed's own links, so it is scoped to.job-header a, .nav aand doesn't bold the story rows.Tests (replace the placeholders): loader (deferred), exact error text for all 5 feeds, invalid page, non-list body, numbering across pages, Prev/More rules, jobs header, More click and keyboard pagination, scroll-to-top, scrollRestoration, URL classification, new-tab attrs, settings effects, job rows, whitespace text, the
commentLabelcases.Shared changes needed
None.
Devin-Org: engineering
Link to Devin session: https://devin-gtm.devinenterprise.com/sessions/cd07a47aec7c48daa5e331248f55d0bd
Open in Devin Desktop: https://devin-gtm.devinenterprise.com/desktop/session/cd07a47aec7c48daa5e331248f55d0bd?variant=devin
Requested by: @ishita-cog
Note
Devin errored when opening this Pull Request as ishita-cog.
As a fallback, Devin opened this PR as itself.
Devin Review