import React, { Component } from "react"; import { withStyles, Typography, Avatar, Divider, Button, CircularProgress, Paper, Tooltip, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Toolbar, IconButton } from "@material-ui/core"; import { styles } from "./PageLayout.styles"; import Mastodon from "megalodon"; import { Account } from "../types/Account"; import { Status } from "../types/Status"; import { Relationship } from "../types/Relationship"; import Post from "../components/Post"; import { withSnackbar } from "notistack"; import { LinkableIconButton } from "../interfaces/overrides"; import { emojifyString } from "../utilities/emojis"; import AccountEditIcon from "mdi-material-ui/AccountEdit"; import PersonAddIcon from "@material-ui/icons/PersonAdd"; import PersonAddDisabledIcon from "@material-ui/icons/PersonAddDisabled"; import AccountMinusIcon from "mdi-material-ui/AccountMinus"; import ChatIcon from "@material-ui/icons/Chat"; import AccountRemoveIcon from "mdi-material-ui/AccountRemove"; import AccountHeartIcon from "mdi-material-ui/AccountHeart"; import OpenInNewIcon from "@material-ui/icons/OpenInNew"; interface IProfilePageState { account?: Account; relationship?: Relationship; posts?: [Status]; viewIsLoading: boolean; viewDidLoad?: boolean; viewDidError?: boolean; viewDidErrorCode?: string; blockDialogOpen: boolean; } class ProfilePage extends Component { client: Mastodon; constructor(props: any) { super(props); this.client = new Mastodon( localStorage.getItem("access_token") as string, localStorage.getItem("baseurl") + "/api/v1" ); this.state = { viewIsLoading: true, blockDialogOpen: false }; } toggleBlockDialog() { if (this.state.relationship && !this.state.relationship.blocking) this.setState({ blockDialogOpen: !this.state.blockDialogOpen }); else this.toggleBlock(); } getAccountData(id: string) { this.client .get(`/accounts/${id}`) .then((resp: any) => { let profile: Account = resp.data; const div = document.createElement("div"); div.innerHTML = profile.note; profile.note = div.textContent || div.innerText || ""; this.setState({ account: profile }); }) .catch((error: Error) => { this.setState({ viewIsLoading: false, viewDidError: true, viewDidErrorCode: error.message }); }); this.getRelationships(); this.client .get(`/accounts/${id}/statuses`) .then((resp: any) => { this.setState({ posts: resp.data, viewIsLoading: false, viewDidLoad: true, viewDidError: false }); }) .catch((err: Error) => { this.setState({ viewIsLoading: false, viewDidError: true, viewDidErrorCode: err.message }); }); } componentWillReceiveProps(props: any) { this.getAccountData(props.match.params.profileId); window.scrollTo(0, 0); } componentWillMount() { const { match: { params } } = this.props; this.getAccountData(params.profileId); } isItMe(): boolean { if (this.state.account) { return ( this.state.account.id === JSON.parse(localStorage.getItem("account") as string).id ); } else { return false; } } getRelationships() { this.client .get("/accounts/relationships", { id: this.props.match.params.profileId }) .then((resp: any) => { let relationship: Relationship = resp.data[0]; this.setState({ relationship }); }) .catch((error: Error) => { this.setState({ viewIsLoading: false, viewDidError: true, viewDidErrorCode: error.message }); }); } loadMoreTimelinePieces() { const { match: { params } } = this.props; this.setState({ viewDidLoad: false, viewIsLoading: true }); if (this.state.posts && this.state.posts.length > 0) { this.client .get(`/accounts/${params.profileId}/statuses`, { max_id: this.state.posts[this.state.posts.length - 1].id, limit: 20 }) .then((resp: any) => { let newPosts: [Status] = resp.data; let posts = this.state.posts as [Status]; if (newPosts.length <= 0) { this.props.enqueueSnackbar("Reached end of posts", { variant: "error" }); } else { newPosts.forEach((post: Status) => { posts.push(post); }); } this.setState({ viewIsLoading: false, viewDidLoad: true, posts }); }) .catch((err: Error) => { this.setState({ viewIsLoading: false, viewDidError: true, viewDidErrorCode: err.message }); this.props.enqueueSnackbar("Failed to get posts", { variant: "error" }); }); } else { this.props.enqueueSnackbar("Reached end of posts", { variant: "error" }); this.setState({ viewIsLoading: false, viewDidLoad: true }); } } toggleFollow() { if (this.state.relationship) { if (this.state.relationship.following) { this.client .post( `/accounts/${ this.state.account ? this.state.account.id : this.props.match.params.profileId }/unfollow` ) .then((resp: any) => { let relationship: Relationship = resp.data; this.setState({ relationship }); this.props.enqueueSnackbar( "You are no longer following this account." ); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't unfollow account: " + err.name, { variant: "error" } ); console.error(err.message); }); } else { this.client .post( `/accounts/${ this.state.account ? this.state.account.id : this.props.match.params.profileId }/follow` ) .then((resp: any) => { let relationship: Relationship = resp.data; this.setState({ relationship }); this.props.enqueueSnackbar( "You are now following this account." ); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't follow account: " + err.name, { variant: "error" } ); console.error(err.message); }); } } } toggleBlock() { if (this.state.relationship) { if (this.state.relationship.blocking) { this.client .post( `/accounts/${ this.state.account ? this.state.account.id : this.props.match.params.profileId }/unblock` ) .then((resp: any) => { let relationship: Relationship = resp.data; this.setState({ relationship }); this.props.enqueueSnackbar( "You are no longer blocking this account." ); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't unblock account: " + err.name, { variant: "error" } ); console.error(err.message); }); } else { this.client .post( `/accounts/${ this.state.account ? this.state.account.id : this.props.match.params.profileId }/block` ) .then((resp: any) => { let relationship: Relationship = resp.data; this.setState({ relationship }); this.props.enqueueSnackbar( "You are now blocking this account." ); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't block account: " + err.name, { variant: "error" } ); console.error(err.message); }); } } } render() { const { classes } = this.props; return (
this.toggleFollow()} > {this.isItMe() ? ( ) : this.state.relationship && this.state.relationship.following ? ( ) : ( )} this.toggleBlockDialog()} > {this.state.relationship && this.state.relationship.blocking ? ( ) : ( )} {this.isItMe() ? ( ) : null}
{this.state.account ? "@" + this.state.account.acct : ""} {this.state.account ? this.state.account.followers_count : 0}{" "} followers |{" "} {this.state.account ? this.state.account.following_count : 0}{" "} following |{" "} {this.state.account ? this.state.account.statuses_count : 0}{" "} posts
{this.state.viewDidError ? ( Bummer. Something went wrong when loading this profile. {this.state.viewDidErrorCode ? this.state.viewDidErrorCode : ""} ) : ( )} {this.state.posts ? (
{this.state.posts.map((post: Status) => { return ( ); })}
{this.state.viewDidLoad && !this.state.viewDidError ? (
this.loadMoreTimelinePieces() } >
) : null}
) : ( )} {this.state.viewIsLoading ? (
) : ( )} this.toggleBlockDialog()} > Block this person? Are you sure you want to block this person? You won't see their posts on your home feed, local timeline, or public timeline.
); } } export default withStyles(styles)(withSnackbar(ProfilePage));