Skip to content

Commit

Permalink
render link posts differently
Browse files Browse the repository at this point in the history
  • Loading branch information
Southclaws committed Nov 2, 2023
1 parent 4fceefc commit 6569458
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 6 deletions.
95 changes: 95 additions & 0 deletions web/src/components/feed/link/LinkPost.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import NextLink from "next/link";

import { Link, ThreadReference } from "src/api/openapi/schemas";
import { useSession } from "src/auth";
import { Byline } from "src/components/content/Byline";
import { CollectionMenu } from "src/components/content/CollectionMenu/CollectionMenu";
import { Heading, LinkBox, LinkOverlay } from "src/theme/components";

import { FeedItemMenu } from "../common/FeedItemMenu/FeedItemMenu";

import { Box, Flex, HStack, VStack, styled } from "@/styled-system/jsx";

type Props = {
thread: ThreadReference;
};

export function LinkPost(props: Props) {
const session = useSession();

const permalink = `/t/${props.thread.slug}`;
const link = props.thread.link as Link;
const asset = link.assets?.[0] ?? props.thread.assets?.[0];

return (
<LinkBox>
<styled.article
display="flex"
flexDir="column"
width="full"
boxShadow="md"
borderRadius="md"
backgroundColor="white"
overflow="hidden"
>
<Box
display="flex"
w="full"
bgColor="accent.100"
overflow="hidden"
height="24"
p="2"
gap="2"
>
{asset && (
<Box flexGrow="1" flexShrink="0" width="32">
<styled.img
src={asset.url}
height="full"
width="full"
objectPosition="left"
objectFit="cover"
/>
</Box>
)}

<VStack
w="full"
alignItems="start"
justifyContent="space-evenly"
gap="0"
p="2"
>
<Flex width="full" justifyContent="space-between">
<Heading size="sm">
<LinkOverlay as={NextLink} href={permalink}>
{props.thread.title}
</LinkOverlay>
</Heading>
</Flex>

<styled.p lineClamp={2}>
<span>{props.thread.short}</span>
&nbsp;•&nbsp;
<styled.span color="gray.500">{link.description}</styled.span>
</styled.p>
</VStack>
</Box>

<Flex justifyContent="space-between" p="2">
<Byline
href={permalink}
author={props.thread.author}
time={new Date(props.thread.createdAt)}
updated={new Date(props.thread.updatedAt)}
/>

<HStack>
{session && <CollectionMenu thread={props.thread} />}
<FeedItemMenu {...props.thread} />
</HStack>
</Flex>
</styled.article>
</LinkBox>
);
}
24 changes: 24 additions & 0 deletions web/src/components/feed/mixed/MixedPostList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ThreadReference } from "src/api/openapi/schemas";
import { EmptyState } from "src/components/feed/EmptyState";

import { styled } from "@/styled-system/jsx";

import { MixedPostListItem } from "./MixedPostListItem";

type Props = {
posts: ThreadReference[];
};

export function MixedPostList(props: Props) {
if (props.posts.length === 0) {
return <EmptyState />;
}

return (
<styled.ol width="full" display="flex" flexDirection="column" gap="4">
{props.posts.map((t) => (
<MixedPostListItem key={t.id} thread={t} />
))}
</styled.ol>
);
}
19 changes: 19 additions & 0 deletions web/src/components/feed/mixed/MixedPostListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ThreadReference } from "src/api/openapi/schemas";

import { LinkPost } from "../link/LinkPost";
import { TextPost } from "../text/TextPost";

import { getPostType } from "./utils";

type Props = {
thread: ThreadReference;
};

export function MixedPostListItem(props: Props) {
switch (getPostType(props.thread)) {
case "link":
return <LinkPost {...props} />;
default:
return <TextPost {...props} />;
}
}
9 changes: 9 additions & 0 deletions web/src/components/feed/mixed/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ThreadReference } from "src/api/openapi/schemas";

export function getPostType(thread: ThreadReference) {
if (thread.link) {
return "link";
}

return "text";
}
4 changes: 2 additions & 2 deletions web/src/screens/feed/Client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { ThreadList } from "src/api/openapi/schemas";
import { useThreadList } from "src/api/openapi/threads";
import { TextPostList } from "src/components/feed/text/TextPostList";
import { MixedPostList } from "src/components/feed/mixed/MixedPostList";
import { Unready } from "src/components/site/Unready";

export function Client(props: { category: string; threads: ThreadList }) {
Expand All @@ -17,5 +17,5 @@ export function Client(props: { category: string; threads: ThreadList }) {

if (!data) return <Unready {...error} />;

return <TextPostList posts={data?.threads} />;
return <MixedPostList posts={data?.threads} />;
}
4 changes: 2 additions & 2 deletions web/src/screens/home/Client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { ThreadList } from "src/api/openapi/schemas";
import { useThreadList } from "src/api/openapi/threads";
import { TextPostList } from "src/components/feed/text/TextPostList";
import { MixedPostList } from "src/components/feed/mixed/MixedPostList";
import { Onboarding } from "src/components/site/Onboarding/Onboarding";
import { Unready } from "src/components/site/Unready";

Expand All @@ -23,7 +23,7 @@ export function Client(props: Props) {
return (
<>
<Onboarding />
<TextPostList posts={data?.threads} />
<MixedPostList posts={data?.threads} />
</>
);
}
4 changes: 2 additions & 2 deletions web/src/screens/profile/components/Content/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@chakra-ui/react";

import { PublicProfile } from "src/api/openapi/schemas";
import { TextPostList } from "src/components/feed/text/TextPostList";
import { MixedPostList } from "src/components/feed/mixed/MixedPostList";
import { Unready } from "src/components/site/Unready";

import { CollectionList } from "../CollectionList/CollectionList";
Expand All @@ -32,7 +32,7 @@ export function Content(props: PublicProfile) {
</TabList>
<TabPanels>
<TabPanel>
<TextPostList posts={content.data.threads} />
<MixedPostList posts={content.data.threads} />
</TabPanel>
<TabPanel>
<Box>
Expand Down
56 changes: 56 additions & 0 deletions web/src/theme/create-style-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"use client";

import {
type ComponentType,
createContext,
forwardRef,
useContext,
} from "react";

type AnyProps = Record<string, unknown>;
type AnyRecipe = {
(props?: AnyProps): Record<string, string>;
splitVariantProps: (props: AnyProps) => any;
};

export const createStyleContext = <R extends AnyRecipe>(recipe: R) => {
const StyleContext = createContext<Record<string, string> | null>(null);

const withProvider = <T extends object>(
Component: ComponentType<T>,
part?: string,
) => {
const Comp = forwardRef((props: T & Parameters<R>[0], ref) => {
const [variantProps, rest] = recipe.splitVariantProps(props);
const styles = recipe(variantProps);
return (
<StyleContext.Provider value={styles}>
<Component ref={ref} className={styles?.[part ?? ""]} {...rest} />
</StyleContext.Provider>
);
});
Comp.displayName = Component.displayName || Component.name;
return Comp;
};

const withContext = <T extends object>(
Component: ComponentType<T>,
part?: string,
) => {
if (!part) return Component;

const Comp = forwardRef((props: T, ref) => {
const styles = useContext(StyleContext);
return (
<Component ref={ref} className={styles?.[part ?? ""]} {...props} />
);
});
Comp.displayName = Component.displayName || Component.name;
return Comp;
};

return {
withProvider,
withContext,
};
};

2 comments on commit 6569458

@vercel
Copy link

@vercel vercel bot commented on 6569458 Nov 2, 2023

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on 6569458 Nov 2, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.