hyperspace-desktop-client-w.../src/pages/Conversation.tsx

152 lines
4.0 KiB
TypeScript

import React, { Component } from "react";
import {
withStyles,
CircularProgress,
Typography,
Paper
} from "@material-ui/core";
import { styles } from "./PageLayout.styles";
import Post from "../components/Post";
import { Status } from "../types/Status";
import { Context } from "../types/Context";
import Mastodon from "megalodon";
import { withSnackbar } from "notistack";
interface IConversationPageState {
posts?: [Status];
viewIsLoading: boolean;
viewDidLoad?: boolean;
viewDidError?: boolean;
viewDidErrorCode?: any;
conversationId: string;
}
class Conversation extends Component<any, IConversationPageState> {
client: Mastodon;
streamListener: any;
constructor(props: any) {
super(props);
this.state = {
viewIsLoading: true,
conversationId: props.match.params.conversationId
};
this.client = new Mastodon(
localStorage.getItem("access_token") as string,
(localStorage.getItem("baseurl") as string) + "/api/v1"
);
}
getContext() {
this.client
.get(`/statuses/${this.state.conversationId}`)
.then((resp: any) => {
let result: Status = resp.data;
this.setState({ posts: [result] });
})
.catch((err: Error) => {
this.setState({
viewIsLoading: false,
viewDidError: true,
viewDidErrorCode: err.message
});
this.props.enqueueSnackbar("Couldn't get conversation: " + err.name, {
variant: "error"
});
});
this.client
.get(`/statuses/${this.state.conversationId}/context`)
.then((resp: any) => {
let context: Context = resp.data;
let posts = this.state.posts;
let array: any[] = [];
if (posts) {
array = array
.concat(context.ancestors)
.concat(posts)
.concat(context.descendants);
}
this.setState({
posts: array as [Status],
viewIsLoading: false,
viewDidLoad: true,
viewDidError: false
});
})
.catch((err: Error) => {
this.setState({
viewIsLoading: false,
viewDidError: true,
viewDidErrorCode: err.message
});
this.props.enqueueSnackbar("Couldn't get conversation: " + err.name, {
variant: "error"
});
});
}
componentWillReceiveProps(props: any) {
if (props.match.params.conversationId !== this.state.conversationId) {
this.getContext();
}
}
componentWillMount() {
this.getContext();
}
componentDidUpdate() {
const where: HTMLElement | null = document.getElementById(
`post_${this.state.conversationId}`
);
if (
where &&
this.state.posts &&
this.state.posts[0].id !== this.state.conversationId
) {
window.scrollTo(0, where.getBoundingClientRect().top);
}
}
render() {
const { classes } = this.props;
return (
<div className={classes.pageLayoutMaxConstraints}>
{this.state.posts ? (
<div>
{this.state.posts.map((post: Status) => {
return <Post key={post.id} post={post} client={this.client} />;
})}
</div>
) : (
<span />
)}
{this.state.viewDidError ? (
<Paper className={classes.errorCard}>
<Typography variant="h4">Bummer.</Typography>
<Typography variant="h6">
Something went wrong when loading this conversation.
</Typography>
<Typography>
{this.state.viewDidErrorCode ? this.state.viewDidErrorCode : ""}
</Typography>
</Paper>
) : (
<span />
)}
{this.state.viewIsLoading ? (
<div style={{ textAlign: "center" }}>
<CircularProgress className={classes.progress} color="primary" />
</div>
) : (
<span />
)}
</div>
);
}
}
export default withStyles(styles)(withSnackbar(Conversation));