feat: タイムラインを作成

This commit is contained in:
usbharu 2023-06-16 10:12:39 +09:00
parent 6b1b6f8bf2
commit 3c55a36fed
8 changed files with 101 additions and 75 deletions

View File

@ -276,6 +276,7 @@ components:
- domain - domain
- screenName - screenName
- description - description
- url
- createdAt - createdAt
properties: properties:
id: id:

View File

@ -0,0 +1,16 @@
import {DefaultApiInterface} from "../generated";
export class ApiWrapper {
api: DefaultApiInterface;
constructor(initApi: DefaultApiInterface) {
this.api = initApi;
console.log(this.api);
console.log(this.postsGet());
}
postsGet = async () => this.api.postsGet()
usersUserNameGet = async (userName: string) => this.api.usersUserNameGet(userName);
}

View File

@ -0,0 +1,5 @@
import {PostResponse, UserResponse} from "../generated";
export type PostDetails = PostResponse & {
user: UserResponse
}

View File

@ -0,0 +1,29 @@
import {Component, Match, Switch} from "solid-js";
import {Home, Lock, Mail, Public} from "@suid/icons-material";
import {IconButton} from "@suid/material";
import {Visibility} from "../generated";
export const ShareScopeIndicator: Component<{ visibility: Visibility }> = (props) => {
return <Switch fallback={<Public/>}>
<Match when={props.visibility == "public"}>
<IconButton>
<Public/>
</IconButton>
</Match>
<Match when={props.visibility == "direct"}>
<IconButton>
<Mail/>
</IconButton>
</Match>
<Match when={props.visibility == "followers"}>
<IconButton>
<Lock/>
</IconButton>
</Match>
<Match when={props.visibility == "unlisted"}>
<IconButton>
<Home/>
</IconButton>
</Match>
</Switch>
}

View File

@ -1,10 +1,11 @@
import {Component, createSignal, Match, Switch} from "solid-js"; import {Component, createSignal} from "solid-js";
import {PostResponse} from "../generated";
import {Box, Card, CardActions, CardContent, CardHeader, IconButton, Menu, MenuItem, Typography} from "@suid/material"; import {Box, Card, CardActions, CardContent, CardHeader, IconButton, Menu, MenuItem, Typography} from "@suid/material";
import {Avatar} from "../atoms/Avatar"; import {Avatar} from "../atoms/Avatar";
import {Favorite, Home, Lock, Mail, MoreVert, Public, Reply, ScreenRotationAlt} from "@suid/icons-material"; import {Favorite, MoreVert, Reply, ScreenRotationAlt} from "@suid/icons-material";
import {PostDetails} from "../model/PostDetails";
import {ShareScopeIndicator} from "../molecules/ShareScopeIndicator";
export const Post: Component<{ post: PostResponse }> = (props) => { export const Post: Component<{ post: PostDetails }> = (props) => {
const [anchorEl, setAnchorEl] = createSignal<null | HTMLElement>(null) const [anchorEl, setAnchorEl] = createSignal<null | HTMLElement>(null)
const open = () => Boolean(anchorEl()); const open = () => Boolean(anchorEl());
const handleClose = () => { const handleClose = () => {
@ -13,7 +14,8 @@ export const Post: Component<{ post: PostResponse }> = (props) => {
return ( return (
<Card> <Card>
<CardHeader avatar={<Avatar src={""}/>} title={"test user"} subheader={"test@test"} <CardHeader avatar={<Avatar src={props.post.user.url + "/icon.jpg"}/>} title={props.post.user.screenName}
subheader={`${props.post.user.name}@${props.post.user.domain}`}
action={<IconButton onclick={(event) => { action={<IconButton onclick={(event) => {
setAnchorEl(event.currentTarget) setAnchorEl(event.currentTarget)
}}><MoreVert/><Menu disableScrollLock anchorEl={anchorEl()} open={open()} onClose={handleClose}><MenuItem }}><MoreVert/><Menu disableScrollLock anchorEl={anchorEl()} open={open()} onClose={handleClose}><MenuItem
@ -36,29 +38,8 @@ export const Post: Component<{ post: PostResponse }> = (props) => {
<Box sx={{marginLeft: "auto"}}> <Box sx={{marginLeft: "auto"}}>
<Typography>{new Date(props.post.createdAt).toDateString()}</Typography> <Typography>{new Date(props.post.createdAt).toDateString()}</Typography>
</Box> </Box>
<Switch fallback={<Public/>}> <ShareScopeIndicator visibility={props.post.visibility}/>
<Match when={props.post.visibility == "public"}>
<IconButton>
<Public/>
</IconButton>
</Match>
<Match when={props.post.visibility == "direct"}>
<IconButton>
<Mail/>
</IconButton>
</Match>
<Match when={props.post.visibility == "followers"}>
<IconButton>
<Lock/>
</IconButton>
</Match>
<Match when={props.post.visibility == "unlisted"}>
<IconButton>
<Home/>
</IconButton>
</Match>
</Switch>
</CardActions> </CardActions>
</Card> </Card>
) )
} }

View File

@ -5,7 +5,7 @@ import {AddPhotoAlternate, Poll, Public} from "@suid/icons-material";
export const PostForm: Component<{ label: string }> = (props) => { export const PostForm: Component<{ label: string }> = (props) => {
return ( return (
<Paper> <Paper sx={{width: "100%"}}>
<Stack> <Stack>
<Stack direction={"row"} spacing={2} sx={{padding: 2}}> <Stack direction={"row"} spacing={2} sx={{padding: 2}}>
<Avatar src={""}/> <Avatar src={""}/>
@ -35,4 +35,4 @@ export const PostForm: Component<{ label: string }> = (props) => {
</Stack> </Stack>
</Paper> </Paper>
) )
} }

View File

@ -1,56 +1,36 @@
import {Component} from "solid-js"; import {Component, createResource} from "solid-js";
import {MainPage} from "../templates/MainPage"; import {MainPage} from "../templates/MainPage";
import {PostForm} from "../organisms/PostForm"; import {PostForm} from "../organisms/PostForm";
import {Stack} from "@suid/material"; import {Stack} from "@suid/material";
import {Post} from "../organisms/Post"; import {DefaultApi} from "../generated";
import {PostResponse} from "../generated"; import {PostDetails} from "../model/PostDetails";
import {PostList} from "../templates/PostList";
import {ApiWrapper} from "../lib/ApiWrapper";
export const TopPage: Component = () => { export const TopPage: Component = () => {
const api = new ApiWrapper(new DefaultApi())
const [posts] = createResource(api.postsGet);
return ( return (
<MainPage> <MainPage>
<Stack spacing={1}> <Stack spacing={1} alignItems={"stretch"}>
<PostForm label={"投稿する"}/> <PostForm label={"投稿する"}/>
<Post post={{ <PostList posts={posts()?.map(value => {
text: "テスト~", return {
sensitive: false, ...value,
apId: "https://example.com", user: {
id: 1234, id: 1234,
createdAt: Date.now(), createdAt: Date.now(),
url: "https://example.com", domain: "test-hideout.usbharu.dev",
userId: 1234, name: "test",
visibility: "public" url: "https://test-hideout.usbharu.dev",
} as PostResponse}></Post> screenName: "test",
<Post post={{ description: ""
text: "テスト 公開範囲", }
sensitive: false, } as PostDetails
apId: "https://example.com", }) ?? []}/>
id: 1234,
createdAt: 1234567,
url: "https://example.com",
userId: 1234,
visibility: "direct"
} as PostResponse}></Post>
<Post post={{
text: "テスト~",
sensitive: false,
apId: "https://example.com",
id: 1234,
createdAt: 1234567,
url: "https://example.com",
userId: 1234,
visibility: "unlisted"
} as PostResponse}></Post>
<Post post={{
text: "テスト~",
sensitive: false,
apId: "https://example.com",
id: 1234,
createdAt: 1234567,
url: "https://example.com",
userId: 1234,
visibility: "followers"
} as PostResponse}></Post>
</Stack> </Stack>
</MainPage> </MainPage>
) )
} }

View File

@ -0,0 +1,14 @@
import {Component, For} from "solid-js";
import {CircularProgress} from "@suid/material";
import {Post} from "../organisms/Post";
import {PostDetails} from "../model/PostDetails";
export const PostList: Component<{ posts: PostDetails[] }> = (props) => {
return (
<For each={props.posts} fallback={<CircularProgress/>}>
{
(item, index) => <Post post={item}/>
}
</For>
)
}