import React, {Component} from 'react'; import {withStyles, Typography, Avatar, Divider, Button, CircularProgress, Paper, Tooltip, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions} 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 { LinkableButton } from '../interfaces/overrides'; import { emojifyString } from '../utilities/emojis'; 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); } 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 }) }); } statElement(classes: any, stat: 'following' | 'followers' | 'posts') { let number = 0; if (this.state.account) { if (stat == 'following') { number = this.state.account.following_count; } else if (stat == 'followers') { number = this.state.account.followers_count; } else if (stat == 'posts') { number = this.state.account.statuses_count; } } return
{number} {stat}
; } 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.state.account ? '@' + this.state.account.acct: ""} {this.state.account ? this.state.account.note: ""}
{this.statElement(classes, 'followers')} {this.statElement(classes, 'following')} {this.statElement(classes, 'posts')}
{ this.state.relationship?
Mention
: null }
{ 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));