import React, { Component } from "react"; import { List, ListItem, ListItemText, ListSubheader, ListItemSecondaryAction, ListItemAvatar, Paper, IconButton, withStyles, Typography, CircularProgress, Button, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Tooltip } from "@material-ui/core"; import AssignmentIndIcon from "@material-ui/icons/AssignmentInd"; import PersonIcon from "@material-ui/icons/Person"; import PersonAddIcon from "@material-ui/icons/PersonAdd"; import DeleteIcon from "@material-ui/icons/Delete"; import { styles } from "./PageLayout.styles"; import { LinkableIconButton, LinkableAvatar } from "../interfaces/overrides"; import ForumIcon from "@material-ui/icons/Forum"; import ReplyIcon from "@material-ui/icons/Reply"; import Mastodon from "megalodon"; import { Notification } from "../types/Notification"; import { Account } from "../types/Account"; import { withSnackbar } from "notistack"; interface INotificationsPageState { notifications?: [Notification]; viewIsLoading: boolean; viewDidLoad?: boolean; viewDidError?: boolean; viewDidErrorCode?: string; deleteDialogOpen: boolean; } class NotificationsPage extends Component { client: Mastodon; streamListener: any; constructor(props: any) { super(props); this.client = new Mastodon( localStorage.getItem("access_token") as string, localStorage.getItem("baseurl") + "/api/v1" ); this.state = { viewIsLoading: true, deleteDialogOpen: false }; } componentWillMount() { this.client .get("/notifications") .then((resp: any) => { let notifications: [Notification] = resp.data; this.setState({ notifications, viewIsLoading: false, viewDidLoad: true }); }) .catch((err: Error) => { this.setState({ viewDidLoad: true, viewIsLoading: false, viewDidError: true, viewDidErrorCode: err.message }); }); } componentDidMount() { this.streamNotifications(); } streamNotifications() { this.streamListener = this.client.stream("/streaming/user"); this.streamListener.on("notification", (notif: Notification) => { let notifications = this.state.notifications; if (notifications) { notifications.unshift(notif); this.setState({ notifications }); } }); } toggleDeleteDialog() { this.setState({ deleteDialogOpen: !this.state.deleteDialogOpen }); } removeHTMLContent(text: string) { const div = document.createElement("div"); div.innerHTML = text; let innerContent = div.textContent || div.innerText || ""; if (innerContent.length > 65) innerContent = innerContent.slice(0, 65) + "..."; return innerContent; } removeNotification(id: string) { this.client .post(`/notifications/${id}/dismiss`) .then((resp: any) => { let notifications = this.state.notifications; if (notifications !== undefined && notifications.length > 0) { notifications.forEach((notification: Notification) => { if ( notifications !== undefined && notification.id === id ) { notifications.splice( notifications.indexOf(notification), 1 ); } }); } this.setState({ notifications }); this.props.enqueueSnackbar("Notification deleted."); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't delete notification: " + err.name, { variant: "error" } ); }); } removeAllNotifications() { this.client .post("/notifications/clear") .then((resp: any) => { this.setState({ notifications: undefined }); this.props.enqueueSnackbar("All notifications deleted."); }) .catch((err: Error) => { this.props.enqueueSnackbar( "Couldn't delete notifications: " + err.name, { variant: "error" } ); }); } createNotification(notif: Notification) { const { classes } = this.props; let primary = ""; let secondary = ""; switch (notif.type) { case "follow": primary = `${notif.account.display_name || notif.account.username} is now following you!`; break; case "mention": primary = `${notif.account.display_name || notif.account.username} mentioned you in a post.`; secondary = this.removeHTMLContent( notif.status ? notif.status.content : "" ); break; case "reblog": primary = `${notif.account.display_name || notif.account.username} reblogged your post.`; secondary = this.removeHTMLContent( notif.status ? notif.status.content : "" ); break; case "favourite": primary = `${notif.account.display_name || notif.account.username} favorited your post.`; secondary = this.removeHTMLContent( notif.status ? notif.status.content : "" ); break; default: if (notif.status && notif.status.poll) { primary = "A poll you voted in or created has ended."; secondary = this.removeHTMLContent( notif.status ? notif.status.content : "" ); } else { primary = "A magical thing happened!"; } break; } return ( {secondary.slice(0, 35) + "..."} {secondary} } /> {notif.type === "follow" ? ( this.followMember(notif.account) } > ) : notif.status ? ( {notif.type === "mention" ? ( ) : null} ) : null} this.removeNotification(notif.id)} > ); } followMember(acct: Account) { this.client .post(`/accounts/${acct.id}/follow`) .then((resp: any) => { 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); }); } render() { const { classes } = this.props; return (
{this.state.viewDidLoad ? ( this.state.notifications && this.state.notifications.length > 0 ? (
Recent notifications {this.state.notifications.map( (notification: Notification) => { return this.createNotification( notification ); } )}
) : (
All clear! It looks like you have no notifications. Why not get the conversation going with a new post?
) ) : null} {this.state.viewDidError ? ( Bummer. Something went wrong when loading this timeline. {this.state.viewDidErrorCode ? this.state.viewDidErrorCode : ""} ) : ( )} {this.state.viewIsLoading ? (
) : ( )} this.toggleDeleteDialog()} > Delete all notifications? Are you sure you want to delete all notifications? This action cannot be undone.
); } } export default withStyles(styles)(withSnackbar(NotificationsPage));