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

248 lines
8.5 KiB
TypeScript

import React, { Component } from "react";
import { styles } from "./PageLayout.styles";
import {
Button,
CircularProgress,
IconButton,
List,
ListItem,
ListItemAvatar,
ListItemSecondaryAction,
ListItemText,
ListSubheader,
Paper,
Typography,
Tooltip,
withStyles,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
TextField
} from "@material-ui/core";
import { withSnackbar } from "notistack";
import DomainIcon from "@material-ui/icons/Domain";
import CloseIcon from "@material-ui/icons/Close";
import Mastodon from "megalodon";
interface IBlockedState {
viewIsLoading: boolean;
viewDidLoad: boolean;
viewDidError: boolean;
addBlockOpen: boolean;
blockedServers?: [string];
blockTextField: string;
}
class Blocked extends Component<any, IBlockedState> {
client: any;
constructor(props: any) {
super(props);
this.client = new Mastodon(
localStorage.getItem("access_token") as string,
localStorage.getItem("baseurl") + "/api/v1"
);
this.state = {
addBlockOpen: false,
viewIsLoading: true,
viewDidLoad: false,
viewDidError: false,
blockTextField: ""
};
}
componentDidMount() {
this.client
.get("/domain_blocks")
.then((resp: any) => {
this.setState({
blockedServers: resp.data,
viewDidLoad: true,
viewIsLoading: false
});
})
.catch((err: Error) => {
console.error(err);
this.setState({
viewIsLoading: false,
viewDidError: true
});
});
}
addBlock(domain: string) {
this.client.post("/domain_blocks", { domain }).then((resp: any) => {
this.props.enqueueSnackbar(`Blocked ${domain} successfully.`);
let blockedServers = this.state.blockedServers;
if (blockedServers && blockedServers.length > 0) {
blockedServers.push(domain);
} else {
blockedServers = [domain];
}
this.setState({
blockTextField: "",
addBlockOpen: false,
blockedServers
});
});
}
removeBlock(domain: string) {
this.client
.del("/domain_blocks", { domain })
.then((resp: any) => {
this.props.enqueueSnackbar(`Removed ${domain} from blacklist.`);
let blockedServers = this.state.blockedServers;
if (blockedServers && blockedServers.length > 0) {
blockedServers.splice(blockedServers.indexOf(domain), 1);
}
this.setState({
blockedServers
});
})
.catch((err: Error) => {
this.props.enqueueSnackbar(
`Couldn't remove ${domain}: ${err.name}`,
{ variant: "error" }
);
});
}
updateTextField(value: string) {
this.setState({
blockTextField: value
});
}
showAddBlockDialog() {
return (
<Dialog
open={this.state.addBlockOpen}
onClose={() => this.toggleAddBlockState()}
>
<DialogTitle id="alert-dialog-title">Add a domain</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Type the domain that you want to block. You won't see
any posts from this server or receive notifications from
them.
</DialogContentText>
<TextField
variant="outlined"
fullWidth
value={this.state.blockTextField}
placeholder="mastodon.online"
onChange={e => this.updateTextField(e.target.value)}
></TextField>
</DialogContent>
<DialogActions>
<Button
onClick={() => this.toggleAddBlockState()}
color="primary"
autoFocus
>
Cancel
</Button>
<Button
color="primary"
onClick={e => this.addBlock(this.state.blockTextField)}
>
Add
</Button>
</DialogActions>
</Dialog>
);
}
toggleAddBlockState() {
this.setState({ addBlockOpen: !this.state.addBlockOpen });
}
render() {
const { classes } = this.props;
return (
<div className={classes.pageLayoutConstraints}>
<ListSubheader>Blocked servers</ListSubheader>
<Button
className={classes.clearAllButton}
variant="text"
onClick={() => this.toggleAddBlockState()}
>
Add
</Button>
{this.state.viewIsLoading ? (
<div style={{ textAlign: "center" }}>
<CircularProgress
className={classes.progress}
color="primary"
/>
</div>
) : (
<span />
)}
{this.state.blockedServers &&
this.state.blockedServers.length > 0 ? (
<Paper className={classes.pageListConstraints}>
<List>
{this.state.blockedServers &&
this.state.blockedServers.length > 0
? this.state.blockedServers.map(
(domain: string) => (
<ListItem key={domain}>
<ListItemAvatar>
<DomainIcon color="action" />
</ListItemAvatar>
<ListItemText primary={domain} />
<ListItemSecondaryAction>
<Tooltip title="Remove block">
<IconButton
onClick={() =>
this.removeBlock(
domain
)
}
>
<CloseIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
)
)
: null}
</List>
</Paper>
) : this.state.viewDidError ? (
<Paper className={classes.errorCard}>
<Typography variant="h4">Bummer.</Typography>
<Typography variant="h6">
Something went wrong when loading blocked servers.
</Typography>
</Paper>
) : (
<Typography variant="h6" component="p">
No blocked servers found.
</Typography>
)}
<br />
<Typography variant={"caption"}>
You won't see any public posts and notifications from the
following servers, and any followers from these servers are
automatically removed.
</Typography>
{this.showAddBlockDialog()}
</div>
);
}
}
export default withStyles(styles)(withSnackbar(Blocked));