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

345 lines
16 KiB
TypeScript

import React, { Component } from "react";
import {
withStyles,
Typography,
CircularProgress,
ListSubheader,
Link,
Paper,
List,
ListItem,
ListItemText,
ListItemAvatar,
ListItemSecondaryAction,
Tooltip,
IconButton
} from "@material-ui/core";
import { styles } from "./PageLayout.styles";
import { UAccount, Account } from "../types/Account";
import { Tag } from "../types/Tag";
import Mastodon from "megalodon";
import { LinkableAvatar, LinkableIconButton } from "../interfaces/overrides";
import moment from "moment";
import FireplaceIcon from "@material-ui/icons/Fireplace";
import TrendingUpIcon from "@material-ui/icons/TrendingUp";
import SearchIcon from "@material-ui/icons/Search";
import OpenInNewIcon from "@material-ui/icons/OpenInNew";
import AssignmentIndIcon from "@material-ui/icons/AssignmentInd";
interface IActivityPageState {
user?: UAccount;
trendingTags?: [Tag];
activeProfileDirectory?: [Account];
newProfileDirectory?: [Account];
viewLoading: boolean;
viewLoaded?: boolean;
viewErrored?: boolean;
}
class ActivityPage extends Component<any, IActivityPageState> {
client: Mastodon;
constructor(props: any) {
super(props);
this.client = new Mastodon(
localStorage.getItem("access_token") as string,
localStorage.getItem("baseurl") + "/api/v1"
);
this.state = {
viewLoading: true
};
}
componentDidMount() {
this.getAccountData();
this.client
.get("/trends", { limit: 3 })
.then((resp: any) => {
let trendingTags: [Tag] = resp.data;
this.setState({ trendingTags });
})
.catch((err: Error) => {
this.setState({
viewLoading: false,
viewErrored: true
});
console.error(err.message);
});
this.client
.get("/directory", { local: true, order: "active", limit: 5 })
.then((resp: any) => {
let profileDirectory: [Account] = resp.data;
this.setState({
activeProfileDirectory: profileDirectory
});
})
.catch((err: Error) => {
this.setState({
viewLoading: false,
viewErrored: true
});
console.error(err.message);
});
this.client
.get("/directory", { local: true, order: "new", limit: 5 })
.then((resp: any) => {
let profileDirectory: [Account] = resp.data;
this.setState({
newProfileDirectory: profileDirectory,
viewLoading: false,
viewLoaded: true
});
})
.catch((err: Error) => {
this.setState({
viewLoading: false,
viewErrored: true
});
console.error(err.message);
});
}
getAccountData() {
this.client
.get("/accounts/verify_credentials")
.then((resp: any) => {
let data: UAccount = resp.data;
this.setState({ user: data });
})
.catch((err: Error) => {
this.props.enqueueSnackbar(
"Couldn't find profile info: " + err.name
);
console.error(err.message);
let acct = localStorage.getItem("account") as string;
this.setState({ user: JSON.parse(acct) });
});
}
render() {
const { classes } = this.props;
return (
<div className={classes.pageLayoutConstraints}>
<div
style={{
textAlign: "center"
}}
>
<FireplaceIcon style={{ fontSize: 64 }} color="action" />
<Typography variant="h6">
Hey there,{" "}
{this.state.user
? this.state.user.display_name ||
this.state.user.acct
: "user"}
!
</Typography>
<Typography paragraph>
Take a look at what's been happening on your instance.
</Typography>
</div>
{this.state.viewLoaded ? (
<div>
<ListSubheader>Trending hashtags</ListSubheader>
{this.state.trendingTags &&
this.state.trendingTags.length > 0 ? (
<Paper>
<List className={classes.pageListConstraints}>
{this.state.trendingTags.map((tag: Tag) => (
<ListItem
id={"trending_tag_" + tag.name}
key={"trending_tag_" + tag.name}
>
<ListItemAvatar>
<TrendingUpIcon />
</ListItemAvatar>
<ListItemText
primary={"#" + tag.name}
secondary={
tag.history
? `${tag.history[0].accounts} people talking in ${tag.history[0].uses} posts`
: "Couldn't determine usage"
}
/>
<ListItemSecondaryAction>
<Tooltip title="Search">
<LinkableIconButton
to={`/search?query=tag:${tag.name}`}
>
<SearchIcon />
</LinkableIconButton>
</Tooltip>
<Tooltip title="View on web">
<IconButton>
<OpenInNewIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
))}
</List>
</Paper>
) : (
<Typography paragraph>
It looks like there aren't any trending tags on
your instance as of right now.
</Typography>
)}
<br />
<ListSubheader>Who's been active</ListSubheader>
{this.state.activeProfileDirectory &&
this.state.activeProfileDirectory.length > 0 ? (
<Paper>
<List className={classes.pageListConstraints}>
{this.state.activeProfileDirectory.map(
(account: Account) => (
<ListItem
key={
"account_active_" +
account.acct
}
id={
"account_active_" +
account.acct
}
>
<ListItemAvatar>
<LinkableAvatar
to={`/profile/${account.id}`}
src={
account.avatar_static
}
/>
</ListItemAvatar>
<ListItemText
primary={
`${account.display_name} (@${account.username})` ||
`@${account.username}`
}
secondary={`Last posted ${moment(
account.last_status_at
)
.startOf("minute")
.fromNow()}`}
/>
<ListItemSecondaryAction>
<Tooltip title="View account">
<LinkableIconButton
to={`/profile/${account.id}`}
>
<AssignmentIndIcon />
</LinkableIconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
)
)}
</List>
</Paper>
) : (
<Typography paragraph>
It looks like there aren't any active people in
the profile directory yet.
</Typography>
)}
<br />
<ListSubheader>New arrivals</ListSubheader>
{this.state.newProfileDirectory &&
this.state.newProfileDirectory.length > 0 ? (
<Paper>
<List className={classes.pageListConstraints}>
{this.state.newProfileDirectory.map(
(account: Account) => (
<ListItem
key={
"account_new_" +
account.acct
}
id={
"account_new_" +
account.acct
}
>
<ListItemAvatar>
<LinkableAvatar
to={`/profile/${account.id}`}
src={
account.avatar_static
}
/>
</ListItemAvatar>
<ListItemText
primary={
`${account.display_name} (@${account.username})` ||
`@${account.username}`
}
secondary={`Joined ${moment(
account.created_at
)
.startOf("minute")
.fromNow()}`}
/>
<ListItemSecondaryAction>
<Tooltip title="View account">
<LinkableIconButton
to={`/profile/${account.id}`}
>
<AssignmentIndIcon />
</LinkableIconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
)
)}
</List>
</Paper>
) : (
<Typography paragraph>
It looks like there aren't any new arrivals
listed in the profile directory yet.
</Typography>
)}
</div>
) : null}
{this.state.viewErrored ? (
<Paper className={classes.errorCard}>
<Typography variant="h4">Bummer.</Typography>
<Typography variant="h6">
Something went wrong when loading instance activity.
</Typography>
</Paper>
) : (
<span />
)}
{this.state.viewLoading ? (
<div style={{ textAlign: "center" }}>
<CircularProgress
className={classes.progress}
color="primary"
/>
</div>
) : (
<span />
)}
<br />
<div>
<Typography variant="caption">
Trending hashtags and the profile directory may not
appear here if your instance isn't up to date. Check the{" "}
<Link href="/#/about">about page</Link> to see if your
instance is running the latest version.
</Typography>
</div>
</div>
);
}
}
export default withStyles(styles)(ActivityPage);