Skip to content

Conversation

@benduran
Copy link
Contributor

@benduran benduran commented Jan 8, 2026

Resolves this Linear ticket

https://linear.app/douro-labs/issue/UI-400/insights-hub-ui-integrate-with-clickhouse-for-grabbing-t-7-data-for

Summary

  • Added a reusable, single day date and datetime picker component to the component-library
  • Swapped the playback speed selector to a dropdown to save on space
  • Removed duckdb and are now querying the ClickhouseDB, directly, for historical data. You can select any day, but any day or time combo might not have data
  • Added storing of UI params to the query string for deep linking and easier sharing for others
  • Improved mobile Layout

Rationale

The previous pyth feeds demo only featured a single, limited day and time window for the historical replay symbols, which didn't make for a very compelling sales pitch.

How has this been tested?

  • Current tests cover my changes
  • Added new tests
  • Manually tested the code

In Action

CleanShot.2026-01-08.at.12.14.53.mp4

… historical fetching to the pyth feeds demo, with URL deeplinking
@benduran benduran requested a review from a team as a code owner January 8, 2026 12:16
@benduran benduran added the enhancement New feature or request label Jan 8, 2026
@vercel
Copy link

vercel bot commented Jan 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
component-library Ready Ready Preview, Comment Jan 9, 2026 3:42pm
developer-hub Ready Ready Preview, Comment Jan 9, 2026 3:42pm
entropy-explorer Ready Ready Preview, Comment Jan 9, 2026 3:42pm
insights Ready Ready Preview, Comment Jan 9, 2026 3:42pm
proposals Ready Ready Preview, Comment Jan 9, 2026 3:42pm
2 Skipped Deployments
Project Deployment Review Updated (UTC)
api-reference Skipped Skipped Jan 9, 2026 3:42pm
staking Skipped Skipped Jan 9, 2026 3:42pm

@vercel vercel bot temporarily deployed to Preview – proposals January 8, 2026 15:00 Inactive
Copy link
Collaborator

@cprussin cprussin left a comment

Choose a reason for hiding this comment

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

Overall looks great! Few interesting discussion points but nothing that needs to change. Very nice!

params: { symbol },
searchParams: { datasources, startAt },
},
} = validatedParams;
Copy link
Collaborator

Choose a reason for hiding this comment

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

total nit and not something to change but ngl I am really not enjoying reading the early return pattern any more having given it more time, I really find this to obscure the control flow of the code and really dislike it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps we should discuss more as a team? The last thing I want is for exhaustion or frustration from anyone on our team when reviewing PRs.

Disclaimer: you've seen my preference for control flow. I find early returns or guard statements to reduce cognitive complexity. I first started using this style a few years ago when I started Golang dev at Netflix, since that is the preferred style in that language (based on the constructs it has available), and while it took some time to get used to, I now find it easier to wrap my head around.

SonarSource released a research paper a few years ago that declared metrics for Cognitive Complexity (they attempted to throw out the Cyclomatic Complexity from the 70s, since that was crafted for the FORTRAN and mainframe days), and the paper penalizes heavy use of statements that break from linear control flow.

The paper's a bit dry, so probably worth an AI summary 😂 : https://www.sonarsource.com/docs/CognitiveComplexity.pdf

Happy to chat with you and the gang more, and I apologize if this style has mentally fatigued you in any way while reviewing (though I appreciate you soldiering forward, regardless)

Comment on lines +22 to +29
<Suspense
fallback={
<div className={classes.suspenseLoader}>
<div>{suspenseLoaderLabel}</div>
<Spinner isIndeterminate label={suspenseLoaderLabel} />
</div>
}
>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nothing that needs to change (I see you're using suspense because you're using query params in PythProAppStateProvider, but more an interesting discussion point that I'd like to discuss with you and get your thoughts on:

Personally I've found suspense to be really clunky and I just don't like the devex of using it:

  • It's implicit, not explicit. The loading state does not happen where the data is loaded, so the code is not obvious, and the fact that there are suspense boundaries or understanding where the boundaries are is not easily traceable from the types or the structure of the code. Knowing how to follow the code could require jumping up many layers in the component tree.
  • It doesn't use the type system for exhaustive state management. In particular, it handles loading promises, but does nothing for errored promises, requiring a separate error boundary (which is IMO a terrible devex). The reality is that anything that can suspend can also fail and not requiring devs to explicitly consider failure is a huge failing.
  • It makes it harder to build skeleton loader states where the skeleton follows the structure of the loaded page, because you end up with a ton of suspense boundaries if you want to do this well and the code gets clunky and obtuse very fast.

I pretty much only use suspense nowadays when it's absolutely required, which is usually one of two cases for SSR:

  1. I'm trying to leverage nextjs app router states which require use of suspense
  2. I'm using a hook that React requires being wrapped in a suspense boundary

Instead, I've found it very pleasant to work with hooks that return data in the way that useData returns -- essentially returning a discriminated union. The app can then switch on state in a way that's explicit and typescript forces devs to acknowledge and handle errors. Additionally because the loading state happens alongside the data that's being loaded, it's very easy to trace and follow the data flow.

const searchParams = useSearchParams();

/** local variables */
const selectedReplayDate = searchParams.get(QUERY_PARAM_START_AT) ?? "";
Copy link
Collaborator

Choose a reason for hiding this comment

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

fyi that we use nuqs elsewhere for dealing with query params that are handled client-side and I've found it to be quite nice

// data to be munged with the new data
...initialState,
});
let query = updateQueryString({
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we actually have to code this to use a let binding and update the query string twice in the case that !isReplaySymbol(source)?

Comment on lines +108 to +110
box-shadow:
0 4px 6px -4px rgb(from black r g b / 10%),
0 10px 15px -3px rgb(from black r g b / 10%);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should probably live in theme.elevations right?

Copy link
Contributor Author

@benduran benduran Jan 9, 2026

Choose a reason for hiding this comment

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

replaced with @include theme.elevation("default", 1);

Comment on lines +93 to +99
const handleHidePicker = useCallback(() => {
isClosingRef.current = true;
setPopoverOpen(false);
setTimeout(() => {
isClosingRef.current = false;
}, 200);
}, []);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be cleaner to use famer-motion to handle the close animations?

(I've been going back and forth on this and there's a lot I don't like about motion, I have strongly considered reverting back from <AnimatePresence> to the old-fashioned timeout syncing, so I'm genuinely looking for your opinion here, not making a suggestion)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants