-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #1459: Added Post and Posts to NextJS #1504
Conversation
import { Box, Grid, Typography, ListSubheader, createStyles } from '@material-ui/core'; | ||
|
||
// For style, need to add: | ||
// import '../styles/telescope-post-content.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: This statement needs to be added to index.tsx
to work properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @tonyvugithub, can you take over the global styling we need? We should get an issue filed to move the telescope-post-content.css file into our global css for next.js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@humphd : I believe @PedroFonsecaDEV is currently working on the global.css file in #1548
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also can we convert the css file of Post to JSS to keep it consistent with the rest of the components? And then we don't have to worry about moving the css to global.css
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can, or we can't do it easily.
The way we load and display posts now is to send raw HTML and inject it as innerHTML
. This means we can't rely on module scoped CSS for a component, since it isn't really a component.
It might be possible down the road to use something like Server Components, but they are still very new. https://addyosmani.com/blog/react-server-components/ has a good discussion. This is a research problem we could tackle on the way to 2.0.
For now, we should probably port it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, left a comment in #1548.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this comment now, @PedroFonsecaDEV is doing it in another PR in the global stylesheet.
@rogercyyu : Hi there, we are in the process of reviewing these migrated to Next PRs. Just wonder if you are still interested to work on this as we would like you to make some changes to your PR. Please let us know in case you decided to drop this then we can assign the issue to others. Thank you. |
@tonyvugithub I am happy to make some changes to this PR. Thanks |
Got it. Thanks. We keep you posted about the progress. |
@@ -0,0 +1,210 @@ | |||
import React, { useRef, useState } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to import React
in next.js, but the other two are fine.
import { Box, Grid, Typography, ListSubheader, createStyles } from '@material-ui/core'; | ||
|
||
// For style, need to add: | ||
// import '../styles/telescope-post-content.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @tonyvugithub, can you take over the global styling we need? We should get an issue filed to move the telescope-post-content.css file into our global css for next.js.
// For style, need to add: | ||
// import '../styles/telescope-post-content.css'; | ||
|
||
interface Props { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The next.js docs/examples on using TypeScript suggest using type
vs. interface
for Props.
// We need a ref to our post content, which we inject into a <section> below. | ||
const sectionEl = useRef(null); | ||
// Grab the post data from our backend so we can render it | ||
const getData = async (url: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should file an issue to switch this to use useSWR
instead.
postUrl: string; | ||
} | ||
|
||
interface DataItem { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really a Post
vs. DataItem
. We probably should create something like this: https://github.com/vercel/next.js/tree/canary/examples/with-typescript/interfaces and move interface Feed {...}
and interface Post {...}
in there, then import them into this file so we can use them.
html: string; | ||
} | ||
|
||
const useStyles = makeStyles((theme) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typing needed on theme
, see https://github.com/mui-org/material-ui/blob/master/examples/nextjs-with-typescript/src/ProTip.tsx#L15
|
||
interface DataItem { | ||
type DataItem = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. The difference here between Props
, which is done correctly, and this (which isn't) is that Props
is internal to this code. Whereas, we'll share the definition of Feed
and Post
throughout the frontend.
We need to create a folder at the same level as components
and include an index.ts
file, like this: https://github.com/vercel/next.js/tree/canary/examples/with-typescript/interfaces
Inside it, you can export
two types:
export type Feed = {
link: string
author: string
}
export type Post {
feed: Feed
id: string
post: string
title: string
updated: string
url: string
html: string
}
Then you can import and use them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the detail feedback
import { useRef, useState } from 'react'; | ||
|
||
import useSWR from 'swr'; | ||
import 'highlight.js/styles/github.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
next.js won't let us do this, we'll have to load this globally, see https://nextjs.org/docs/basic-features/built-in-css-support.
return res.json(); | ||
}; | ||
|
||
const { data: post, error } = useSWR<PostType>(postUrl, getData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you have both a fetch and a useSWR way in the same file. Can we just do useSWR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean, change to:
// Grab the post data from our backend so we can render it
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const { data: post, error } = useSWR<Post>(postUrl, fetcher);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, you don't need to fetch()
and useSWR()
, they accomplish the same thing, and the latter is better (it will cache it for offline use).
|
||
function LoadAutoScroll({ onScroll }: Scroll) { | ||
const classes = useStyles(); | ||
const $buttonRef = useRef(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, if I fixed this correctly.
import { usePrevious } from 'react-use'; | ||
import SentimentDissatisfiedRoundedIcon from '@material-ui/icons/SentimentDissatisfiedRounded'; | ||
import Timeline from './Timeline'; | ||
// TODO: Change these to new ones whenever import to NextJS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got these finished and merged now, if you want to rebase.
import useSiteMetaData from '../../hooks/use-site-metadata'; | ||
|
||
type Props = { | ||
pages: Array<any> | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be an Array of Post objects, so we should be able to type it with your interface.
author: string; | ||
}; | ||
|
||
export type PostType = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the *Type
suffix.
src/frontend/next/src/pages/_app.tsx
Outdated
@@ -1,5 +1,7 @@ | |||
import { AppProps } from 'next/app'; | |||
import '../styles/globals.css'; | |||
import '../styles/empty.css'; | |||
import '../styles/Post.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These won't work here, needs to be globally imported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, those are mistakes leftover from testing.
import { Box, Grid, Typography, ListSubheader, createStyles } from '@material-ui/core'; | ||
|
||
// For style, need to add: | ||
// import '../styles/telescope-post-content.css'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this comment now, @PedroFonsecaDEV is doing it in another PR in the global stylesheet.
return `Last Updated ${formatted}`; | ||
}; | ||
|
||
const Post = ({ postUrl }: Props) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't have 2 things named Post. You are importing a Post
type, and now defining another Post
as the component. You could call this PostComponent
if you want.
const Post = ({ postUrl }: Props) => { | ||
const classes = useStyles(); | ||
// We need a ref to our post content, which we inject into a <section> below. | ||
const sectionEl = useRef(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should type this: useRef<HTMLSectionElement>();
I think.
// Grab the post data from our backend so we can render it | ||
const fetcher = (url: string) => fetch(url).then((r) => r.json()); | ||
|
||
const { data: post, error } = useSWR<PostType>(postUrl, fetcher); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Post vs. PostType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I don't think we need this fetcher
since it's the default. You can drop the second arg and delete line 110, 111.
return ( | ||
<Box className={classes.root} boxShadow={2}> | ||
<ListSubheader className={classes.header}> | ||
<AdminButtons /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to import AdminButtons
to use it here. It's happening in #1515, which we need to land to get it here.
|
||
<Grid container justify="center"> | ||
<Grid item className={classes.spinner}> | ||
<Spinner animation="border" variant="light"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need Spinner, see #1479
@@ -0,0 +1,58 @@ | |||
import { FC } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can drop this.
import useSiteMetaData from '../../hooks/use-site-metadata'; | ||
|
||
type Props = { | ||
pages: Array<typeof Post> | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array<Post>
@@ -0,0 +1,127 @@ | |||
.telescope-post-content { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file can be removed, @PedroFonsecaDEV is doing it globally.
This PR looks good. const AdminButtons = () => <h3> AdminButtons<h3> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for jumping on these fixes, we really need this PR to land soon, so the new frontend can be tested with our backend data.
observer.observe($buttonRef.current!); | ||
|
||
return () => { | ||
observer.unobserve($buttonRef.current!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -0,0 +1,107 @@ | |||
import { useState, useEffect } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file can be renamed to src/frontend/next/src/components/Posts/index.tsx
import useSiteMetaData from '../../hooks/use-site-metadata'; | ||
import useFaviconBadge from '../../hooks/use-favicon-badge'; | ||
|
||
interface PostData { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use a proper Post type from our interfaces?
* Fixed eslint issues (hopefully) & PR changes
Your welcome. Happy to help! |
@rogercyuu is this ready for re-review then? |
@humphd yup |
|
||
// Iterate over all the pages (an array of arrays) and then convert all post | ||
// elements to <Post> | ||
const postsTimeline = pages.map((page: Post[]): any => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@humphd : What does this mean in TS? I thought page already have type Post[]. The return? If so it would return a list of , no idea how to express that in syntax
import Timeline from './Timeline'; | ||
import useSiteMetaData from '../../hooks/use-site-metadata'; | ||
import useFaviconBadge from '../../hooks/use-favicon-badge'; | ||
import { Post } from '../../interfaces/index'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think index work here as Posts have dependent component. Instead of doing /Posts/Posts.tsx
, no?
@@ -0,0 +1,190 @@ | |||
import { useRef, useState } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like you can just move this Posts.tsx component inside the Posts folder.
|
||
// Iterate over all the pages (an array of arrays) and then convert all post | ||
// elements to <Post> | ||
const postsTimeline = pages.map((page: Post[]): any => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rogercyyu : I would say keep any for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well Done!
There are somet things that need to be fixed
@rogercyyu, how did you tested the PR? |
@PedroFonsecaDEV hmmm works fine on my end. Not sure what's happening. I used the |
The infinity scroll starts an infinite loop after 4+ posts loads. |
I want to land this today, what's missing that needs to happen? If there's a scrolling bug, let's file that for follow-up vs holding this up. Please update ASAP. |
Looks like a rebase is needed for sure... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is good for 1.5, and we can fix anything that comes of it in follow-ups.
const [currentPostId, setCurrentPostId] = useState<string | null>(); | ||
|
||
const { data, size, setSize, error } = useSWRInfinite<Post[]>( | ||
(index: number) => `${telescopeUrl}/posts?page=${index + 1}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I load https://deploy-preview-1504--telescope-next.netlify.app/ it looks like telescopeUrl
is undefined on Netlify, it is loading this URL:
https://deploy-preview-1504--telescope-next.netlify.app/undefined/posts?page=1
Filed #1589 to deal with this.
Issue This PR Addresses
This issue address #1459.
Type of Change
Description
This port
Post/
andPosts/
to Next,js and converts it to TypeScript (most i think?).telescope-post-content.css
to\styles
.Thoughts?
Thank you for your time and review.
Checklist